Merge branch 'upstream-master' into merge-from-upstream

Conflicts:
	SoObjects/SOGo/LDAPSource.m
	SoObjects/SOGo/SOGoUserManager.m
This commit is contained in:
Julio García
2015-06-02 12:27:20 +02:00
152 changed files with 6559 additions and 625 deletions
@@ -0,0 +1,67 @@
"Inviting the following persons is prohibited:" = "Ondorengo pertsonak gonbidatzea debekatuta dago:";
"Personal Calendar" = "Egutegi pertsonala";
vevent_class0 = "(Ekitaldi publikoa)";
vevent_class1 = "(Ekitaldi pribatua)";
vevent_class2 = "(Isilpeko ekitaldia)";
vtodo_class0 = "(Zeregin publikoa)";
vtodo_class1 = "(Zeregin pribatua)";
vtodo_class2 = "(Isilpeko egitekoa)";
/* Receipts */
"The event \"%{Summary}\" was created" = "\"%{Summary}\" ekitaldia sortu da";
"The event \"%{Summary}\" was deleted" = "\"%{Summary}\" ekitaldia ezabatu da";
"The event \"%{Summary}\" was updated" = "\"%{Summary}\" ekitaldia eguneratu da";
"The following attendees(s) were notified:" = "Ondorengo partaidea(k) jakinarazi d(ir)a:";
"The following attendees(s) were added:" = "Ondorengo partaidea(k) gehitu d(ir)a:";
"The following attendees(s) were removed:" = "Ondorengo partaidea(k) ezabatu d(ir)a:";
/* IMIP messages */
"calendar_label" = "Egutegia";
"startDate_label" = "Hasi:";
"endDate_label" = "Amaitu:";
"due_label" = "Epemuga:";
"location_label" = "Kokapena:";
"summary_label" = "Laburpena:";
"comment_label" = "Iruzkina:";
/* Invitation */
"Event Invitation: \"%{Summary}\"" = "Ekitaldirako gonbidapena: \"%{Summary}\"";
"(sent by %{SentBy}) " = "(%{SentBy}-k bidalia) ";
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}-k gonbidatu zaitu %{Summary}.-ra\n\nHasiera: %{StartDate}\nAmaiera: %{EndDate}\nDeskribapena: %{Description}";
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}-k gonbidatu zaitu %{Summary}-ra \n\nHasiera: %{StartDate}-an, %{StartTime}-tan\nEnd: %{EndDate}-an, %{EndTime}-tan\nDeskribapena: %{Description}";
/* Deletion */
"Event Cancelled: \"%{Summary}\"" = "Ekitaldia bertan behera utzi da: \"%{Summary}\"";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
= "%{Organizer} %{SentByText} ekitaldi hau bertan behera utzi du: %{Summary}.\n\nHasiera: %{StartDate}\nAmaiera: %{EndDate}\nDEskribapena: %{Description}";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
= "%{Organizer} %{SentByText}-k honako ekitaldia bertan behera utzi du: %{Summary}.\n\nHasiera: %{StartDate}-an, %{StartTime}-tan\nAmaiera: %{EndDate}-an %{EndTime}-tan\nDeskribapena: %{Description}";
/* Update */
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
= "%{OldStartDate} eguneko \"%{Summary}\" hitzordua aldatu da";
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
= "%{OldStartDate} eguneko eta %{OldStartTime} orduko \"%{Summary}\" hitzordua aldatu da";
"The following parameters have changed in the \"%{Summary}\" meeting:"
= " \"%{Summary}\" bilerako ondorengo parametroak aldatu dira:";
"Please accept or decline those changes."
= "Mesedez, onartu edo ezetsi ondorengo aldaketak.";
/* Reply */
"Accepted invitation: \"%{Summary}\"" = "Gonbidapena onartua: \"%{Summary}\"";
"Declined invitation: \"%{Summary}\"" = "Ezetzitako gonbidapena: \"%{Summary}\"";
"Delegated invitation: \"%{Summary}\"" = "Delegatutako gonbidapena: \"%{Summary}\"";
"Not yet decided on invitation: \"%{Summary}\"" = "\"%{Summary}\" gonbidapenari buruz erabaki gabe";
"%{Attendee} %{SentByText}has accepted your event invitation."
= "%{Attendee} %{SentByText} -k zure gonbidapena onartu du.";
"%{Attendee} %{SentByText}has declined your event invitation."
= "%{Attendee} %{SentByText}-k zure gonbidapenari uko egin dio.";
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
= "%{Attendee} %{SentByText}-k zure gonbidapena %{Delegate}-ri delegatu dio.";
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
= "%{Attendee} %{SentByText}-k ez du oraindik zure gonbidapenari buruz erabakirik hartu.";
/* Resources */
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Ezin da honako baliabidea atzitu: \"%{Cn} %{SystemEmail}\"";
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "\"%{Cn} %{SystemEmail}\" baliabidearentzako gehienezko erreserba kopurura (%{NumberOfSimultaneousBookings}) iritsi gara. Gatazka sortu duen ekitaldia \"%{EventTitle}\" da, eta %{StartDate}-n hasten da.";
@@ -56,7 +56,7 @@ vtodo_class2 = "(Tarefa Confidencial)";
"%{Attendee} %{SentByText}has accepted your event invitation."
= "%{Attendee} %{SentByText}foi aceitado seu convite ao evento.";
"%{Attendee} %{SentByText}has declined your event invitation."
= "%{Attendee} %{SentByText}foi declinado seu convite ao evento.";
= "%{Attendee} %{SentByText}recusou seu convite para o evento.";
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
= "%{Attendee} %{SentByText} delegou o convite para %{Delegate}.";
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
+1 -1
View File
@@ -54,7 +54,7 @@ Appointments_RESOURCE_FILES += \
MSExchangeFreeBusySOAPResponseMap.plist \
MSExchangeFreeBusySOAPRequest.wo
Appointments_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
Appointments_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
Appointments_LOCALIZED_RESOURCE_FILES = Localizable.strings
@@ -70,11 +70,27 @@
to: (NSCalendarDate *) newEndDate
{
ASSIGN(address, newAddress);
ASSIGN(startDate, newStartDate);
ASSIGN(endDate, newEndDate);
startDate = [NSCalendarDate dateWithYear: [newStartDate yearOfCommonEra]
month: [newStartDate monthOfYear]
day: [newStartDate dayOfMonth]
hour: [newStartDate hourOfDay]
minute: [newStartDate minuteOfHour]
second: [newStartDate secondOfMinute]
timeZone: [newStartDate timeZone]];
endDate = [NSCalendarDate dateWithYear: [newEndDate yearOfCommonEra]
month: [newEndDate monthOfYear]
day: [newEndDate dayOfMonth]
hour: [newEndDate hourOfDay]
minute: [newEndDate minuteOfHour]
second: [newEndDate secondOfMinute]
timeZone: [newEndDate timeZone]];
[startDate setTimeZone: timeZone];
[endDate setTimeZone: timeZone];
[startDate retain];
[endDate retain];
}
- (NSString *) serverVersion
@@ -502,12 +502,12 @@ static Class iCalEventK = nil;
BOOL is_owner;
userLogin = [[context activeUser] login];
is_owner = [userLogin isEqualToString: [self ownerInContext: context]];
is_owner = [userLogin isEqualToString: self->owner];
// Check if the owner (not the active user) has excluded the calendar from her/his free busy data.
excludeFromFreeBusy
= [self folderPropertyValueInCategory: @"FreeBusyExclusions"
forUser: [SOGoUser userWithLogin: userLogin]];
forUser: [context activeUser]];
if ([self isSubscription])
{
@@ -800,7 +800,7 @@ static Class iCalEventK = nil;
/**
* Set the timezone of the event start and end dates to the user's timezone.
* @param theRecord a dictionnary with the attributes of the event.
* @param theRecord a dictionary with the attributes of the event.
* @return a copy of theRecord with adjusted dates.
*/
- (NSMutableDictionary *) _fixupRecord: (NSDictionary *) theRecord
@@ -2814,7 +2814,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
@"c_category", @"c_classification", @"c_isallday",
@"c_isopaque", @"c_participants", @"c_partmails",
@"c_partstates", @"c_sequence", @"c_priority",
@"c_cycleinfo", @"c_iscycle", @"c_nextalarm", nil];
@"c_cycleinfo", @"c_iscycle", @"c_nextalarm", @"c_description", nil];
return [self fetchFields: infos from: _startDate to: _endDate title: title
component: _component
+10 -4
View File
@@ -421,11 +421,14 @@
SOGoUserSettings *us;
NSMutableArray *unavailableAttendees;
NSEnumerator *enumerator;
NSString *currentUID, *ownerUID, *whiteListString;
NSString *currentUID, *ownerUID;
NSMutableString *reason;
NSDictionary *values;
NSMutableDictionary *value, *moduleSettings, *whiteList;
NSMutableDictionary *value, *moduleSettings;
id whiteList;
int i, count;
i = count = 0;
// Build list of the attendees uids without ressources
@@ -447,8 +450,11 @@
if (![user isResource] && [[moduleSettings objectForKey:@"PreventInvitations"] boolValue])
{
// Check if the user have a whiteList
whiteListString = [moduleSettings objectForKey:@"PreventInvitationsWhitelist"];
whiteList = [whiteListString objectFromJSONString];
whiteList = [moduleSettings objectForKey:@"PreventInvitationsWhitelist"];
// For backward <= 2.2.17 compatibility
if ([whiteList isKindOfClass: [NSString class]])
whiteList = [whiteList objectFromJSONString];
// If the filter have a hit, do not add the currentUID to the unavailableAttendees array
if (![whiteList objectForKey:ownerUID])
+6
View File
@@ -248,6 +248,12 @@
else
[row setObject: [NSNull null] forKey: @"c_category"];
/* handle description */
if ([self comment])
[row setObject: [self comment] forKey: @"c_description"];
else
[row setObject: [NSNull null] forKey: @"c_description"];
return row;
}
+6
View File
@@ -177,6 +177,12 @@
[row setObject: [categories componentsJoinedByString: @","]
forKey: @"c_category"];
/* handle description */
if ([self comment])
[row setObject: [self comment] forKey: @"c_description"];
else
[row setObject: [NSNull null] forKey: @"c_description"];
return row;
}
@@ -0,0 +1,2 @@
"Personal Address Book" = "Helbide liburu pertsonala";
"Collected Address Book" = "Bildutako helbide liburua";
@@ -1,2 +1,2 @@
"Personal Address Book" = "Livro de Endereços Pessoais";
"Personal Address Book" = "Livro de Endereço Pessoal";
"Collected Address Book" = "Catálogos Coletados";
+1 -1
View File
@@ -27,7 +27,7 @@ Contacts_OBJC_FILES = \
Contacts_RESOURCE_FILES += \
product.plist \
Contacts_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
Contacts_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
Contacts_LOCALIZED_RESOURCE_FILES = Localizable.strings
@@ -0,0 +1,2 @@
"OtherUsersFolderName" = "Beste erabiltzaileak";
"SharedFoldersName" = "Partekatutako karpetak";
+1 -1
View File
@@ -92,7 +92,7 @@ Mailer_RESOURCE_FILES += \
SOGoMailWelshReply.wo
Mailer_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
Mailer_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
Mailer_LOCALIZED_RESOURCE_FILES = Localizable.strings
@@ -0,0 +1,16 @@
<#newLine/>
<#newLine/>
<#signaturePlacementOnTop><#newLine/>
<#signature/><#newLine/></#signaturePlacementOnTop>
-------- Original Message --------<#newLine/>
Gaia: <#subject/><#newLine/>
Data: <#date/><#newLine/>
Nork: <#from/><#newLine/>
<#hasReplyTo>Erantzun-honi: <#replyTo/></#hasReplyTo><#hasOrganization>Erakundea: <#organization/></#hasOrganization>Nori: <#to/><#newLine/>
<#hasCc>Kopia: <#cc/></#hasCc><#hasNewsGroups>Berri-taldeak: <#newsgroups/></#hasNewsGroups><#hasReferences>Erreferentziak: <#references/></#hasReferences><#newLine/>
<#newLine/>
<#messageBody/><#newLine/>
<#signaturePlacementOnBottom><#newLine/>
<#newLine/>
<#signature/></#signaturePlacementOnBottom>
<#newLine/>
@@ -0,0 +1,97 @@
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
@@ -0,0 +1,16 @@
<#replyPlacementOnTop><#newLine/>
<#newLine/>
</#replyPlacementOnTop><#signaturePlacementOnTop><#newLine/>
<#signature/><#newLine/>
</#signaturePlacementOnTop><#outlookMode>-------- Jatorrizko Mezua --------<#newLine/>
Gaia: <#subject/><#newLine/>
Data: <#date/><#newLine/>
Nork: <#from/><#newLine/>
<#hasReplyTo>Erantzun-honi: <#replyTo/></#hasReplyTo><#hasOrganization>Erakundea: <#organization/></#hasOrganization>Nori: <#to/><#newLine/>
<#hasCc>Kopia: <#cc/></#hasCc><#hasNewsGroups>Berri-taldeak: <#newsgroups/></#hasNewsGroups><#hasReferences>Erreferentziak: <#references/></#hasReferences></#outlookMode><#newLine/>
<#standardMode><#date/>-an, <#from/>-k idatzi zuen:</#standardMode><#newLine/>
<#newLine/>
<#messageBody/><#newLine/>
<#replyPlacementOnBottom><#newLine/>
<#newLine/>
</#replyPlacementOnBottom><#signaturePlacementOnBottom><#signature/></#signaturePlacementOnBottom><#newLine/>
@@ -0,0 +1,106 @@
outlookMode: WOConditional {
condition = outlookMode;
}
standardMode: WOConditional {
condition = outlookMode;
negate = YES;
}
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
replyPlacementOnTop: WOConditional {
condition = replyPlacementOnTop;
}
replyPlacementOnBottom: WOConditional {
condition = replyPlacementOnTop;
negate = YES;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}
+7
View File
@@ -384,6 +384,11 @@ static BOOL debugSoParts = NO;
_path = [_path componentsSeparatedByString: @"."];
}
// deal with mails of type text/calendar
if ([[[info valueForKey: @"type"] lowercaseString] isEqualToString: @"text"] &&
[[[info valueForKey: @"subtype"] lowercaseString] isEqualToString: @"calendar"])
return info;
/*
For each path component, eg 1,1,3
@@ -772,6 +777,8 @@ static BOOL debugSoParts = NO;
filename = [NSString stringWithFormat: @"unknown_%@", path];
else if ([mimeType isEqualToString: @"message/rfc822"])
filename = [NSString stringWithFormat: @"email_%@.eml", path];
else if ([mimeType isEqualToString: @"text/calendar"])
filename = [NSString stringWithFormat: @"calendar_%@.ics", path];
if (filename)
-2
View File
@@ -1,2 +0,0 @@
config.h
md4.c
+1 -1
View File
@@ -159,7 +159,7 @@ SOGo_OBJC_FILES = \
\
SOGoCredentialsFile.m
SOGo_C_FILES = lmhash.c
SOGo_C_FILES += lmhash.c
SOGo_RESOURCE_FILES = \
SOGoDefaults.plist \
+1 -2
View File
@@ -30,8 +30,7 @@ SOGo_LIBRARIES_DEPEND_UPON += \
ifeq ($(HAS_LIBRARY_gnutls),yes)
ADDITIONAL_CPPFLAGS += -DHAVE_GNUTLS=1
SOGo_LIBRARIES_DEPEND_UPON += -lgnutls
ADDITIONAL_INCLUDE_DIRS += -I$(GNULIB_INCLUDE)
SOGo_C_FILES += $(GNULIB_FILES)
SOGo_C_FILES += md4.c
else
ifeq ($(HAS_LIBRARY_ssl),yes)
ADDITIONAL_CPPFLAGS += -DHAVE_OPENSSL=1
+1 -1
View File
@@ -737,7 +737,7 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
}
NS_HANDLER
{
if ([[localException name] isEqual: @"LDAPException"] &&
if ([[localException name] isEqual: @"LDAPException"] &&
([[[localException userInfo] objectForKey: @"error_code"] intValue] == LDAP_CONSTRAINT_VIOLATION))
{
*perr = PolicyInsufficientPasswordQuality;
+3 -1
View File
@@ -39,7 +39,7 @@
#include <stdint.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include <md4.h>
#include "md4.h"
#define MD4_DIGEST_LENGTH 16
#define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20
@@ -54,6 +54,8 @@
#error this module requires either gnutls or openssl
#endif
#include "lmhash.h"
#import <Foundation/NSArray.h>
#import <NGExtensions/NGBase64Coding.h>
#import "NSData+Crypto.h"
+1 -1
View File
@@ -39,7 +39,7 @@
SOGoLoginModule = "Mail";
SOGoLanguage = "English";
SOGoSupportedLanguages = ( "Arabic", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English",
SOGoSupportedLanguages = ( "Arabic", "Basque", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English",
"SpanishSpain", "SpanishArgentina", "Finnish", "French", "German",
"Icelandic", "Italian", "Hungarian", "BrazilianPortuguese",
"NorwegianBokmal", "NorwegianNynorsk", "Polish", "Russian", "Slovak",
+1 -3
View File
@@ -262,9 +262,7 @@
// The domain is probably appended to the username;
// make sure it is defined as a domain in the configuration.
*theDomain = [*theLogin substringFromIndex: (r.location + r.length)];
if ([[sd domainIds] containsObject: *theDomain])
*theLogin = [*theLogin substringToIndex: r.location];
else
if (![[sd domainIds] containsObject: *theDomain])
*theDomain = nil;
}
}
+3 -1
View File
@@ -1,6 +1,6 @@
/* SOGoSystemDefaults.h - this file is part of SOGo
*
* Copyright (C) 2009-2014 Inverse inc.
* Copyright (C) 2009-2015 Inverse inc.
*
* 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
@@ -64,6 +64,8 @@
- (BOOL) uixAdditionalPreferences;
- (BOOL) uixDebugEnabled;
- (BOOL) easDebugEnabled;
- (NSString *) pageTitle;
- (NSArray *) supportedLanguages;
+6 -1
View File
@@ -1,6 +1,6 @@
/* SOGoSystemDefaults.m - this file is part of SOGo
*
* Copyright (C) 2009-2014 Inverse inc.
* Copyright (C) 2009-2015 Inverse inc.
* Copyright (C) 2012 Jeroen Dekkers <jeroen@dekkers.ch>
*
* This file is free software; you can redistribute it and/or modify
@@ -427,6 +427,11 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict,
return [self boolForKey: @"SOGoUIxDebugEnabled"];
}
- (BOOL) easDebugEnabled
{
return [self boolForKey: @"SOGoEASDebugEnabled"];
}
- (NSString *) pageTitle
{
return [self stringForKey: @"SOGoPageTitle"];
+37 -4
View File
@@ -504,16 +504,49 @@ static Class NSNullK;
SOGoSystemDefaults *dd;
BOOL checkOK;
if (*_domain && [_login rangeOfString: @"@"].location == NSNotFound)
username = [NSString stringWithFormat: @"%@@%@", _login, *_domain];
dd = [SOGoSystemDefaults sharedSystemDefaults];
username = _login;
if (*_domain)
{
if ([_login rangeOfString: @"@"].location == NSNotFound)
username = [NSString stringWithFormat: @"%@@%@", _login, *_domain];
}
else
username = _login;
{
NSRange r;
// We try to extract the domain in use in order to avoid pounding all the authentication
// sources if SOGoLoginDomains isn't specified. This is also true if the user is
// using DAV or EAS.
r = [username rangeOfString: @"@"];
if (r.location != NSNotFound)
{
NSArray *allDomains;
int i;
*_domain = [username substringFromIndex: r.location+1];
allDomains = [[dd dictionaryForKey: @"domains"] allValues];
for (i = 0; i < [allDomains count]; i++)
{
if ([*_domain isEqualToString: [[allDomains objectAtIndex: i] objectForKey: @"SOGoMailDomain"]])
break;
}
// We haven't found one
if (i == [allDomains count])
*_domain = nil;
}
}
// We check the fail count per user in memcache (per server). If the
// fail count reaches X in Y minutes, we deny immediately the
// authentications for Z minutes
failedCount = [[SOGoCache sharedCache] failedCountForLogin: username];
dd = [SOGoSystemDefaults sharedSystemDefaults];
if (failedCount)
{
unsigned int current_time, start_time, delta, block_time;
+381
View File
@@ -0,0 +1,381 @@
/* Functions to compute MD4 message digest of files or memory blocks.
according to the definition of MD4 in RFC 1320 from April 1992.
Copyright (C) 1995-1997, 1999-2003, 2005-2006, 2008-2011 Free Software
Foundation, Inc.
This program 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 program 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; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Adapted by Simon Josefsson from gnulib md5.? and Libgcrypt
cipher/md4.c . */
#include "md4.h"
#include <stdalign.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#endif
#ifdef WORDS_BIGENDIAN
# define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#else
# define SWAP(n) (n)
#endif
#define BLOCKSIZE 32768
#if BLOCKSIZE % 64 != 0
# error "invalid BLOCKSIZE"
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1320, 3.1: Step 1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
/* Initialize structure containing state of computation.
(RFC 1320, 3.3: Step 3) */
void
md4_init_ctx (struct md4_ctx *ctx)
{
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
}
/* Copy the 4 byte value from v into the memory location pointed to by *cp,
If your architecture allows unaligned access this is equivalent to
* (uint32_t *) cp = v */
static inline void
set_uint32 (char *cp, uint32_t v)
{
memcpy (cp, &v, sizeof v);
}
/* Put result from CTX in first 16 bytes following RESBUF. The result
must be in little endian byte order. */
void *
md4_read_ctx (const struct md4_ctx *ctx, void *resbuf)
{
char *r = resbuf;
set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A));
set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B));
set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C));
set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D));
return resbuf;
}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF. */
void *
md4_finish_ctx (struct md4_ctx *ctx, void *resbuf)
{
/* Take yet unprocessed bytes into account. */
uint32_t bytes = ctx->buflen;
size_t pad;
/* Now count remaining bytes. */
ctx->total[0] += bytes;
if (ctx->total[0] < bytes)
++ctx->total[1];
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
memcpy (&((char*)ctx->buffer)[bytes], fillbuf, pad);
/* Put the 64-bit file length in *bits* at the end of the buffer. */
ctx->buffer[(bytes + pad) / 4] = SWAP (ctx->total[0] << 3);
ctx->buffer[(bytes + pad) / 4 + 1] = SWAP ((ctx->total[1] << 3) |
(ctx->total[0] >> 29));
/* Process last bytes. */
md4_process_block (ctx->buffer, bytes + pad + 8, ctx);
return md4_read_ctx (ctx, resbuf);
}
/* Compute MD4 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 16 bytes
beginning at RESBLOCK. */
int
md4_stream (FILE * stream, void *resblock)
{
struct md4_ctx ctx;
size_t sum;
char *buffer = malloc (BLOCKSIZE + 72);
if (!buffer)
return 1;
/* Initialize the computation context. */
md4_init_ctx (&ctx);
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
while (1)
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
if (sum == BLOCKSIZE)
break;
if (n == 0)
{
/* Check for the error flag IFF N == 0, so that we don't
exit the loop after a partial read due to e.g., EAGAIN
or EWOULDBLOCK. */
if (ferror (stream))
{
free (buffer);
return 1;
}
goto process_partial_block;
}
/* We've read at least one byte, so ignore errors. But always
check for EOF, since feof may be true even though N > 0.
Otherwise, we could end up calling fread after EOF. */
if (feof (stream))
goto process_partial_block;
}
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0
*/
md4_process_block (buffer, BLOCKSIZE, &ctx);
}
process_partial_block:;
/* Process any remaining bytes. */
if (sum > 0)
md4_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
md4_finish_ctx (&ctx, resblock);
free (buffer);
return 0;
}
/* Compute MD4 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
void *
md4_buffer (const char *buffer, size_t len, void *resblock)
{
struct md4_ctx ctx;
/* Initialize the computation context. */
md4_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */
md4_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */
return md4_finish_ctx (&ctx, resblock);
}
void
md4_process_bytes (const void *buffer, size_t len, struct md4_ctx *ctx)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
memcpy (&((char*)ctx->buffer)[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 64)
{
md4_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len >= 64)
{
#if !_STRING_ARCH_unaligned
# define UNALIGNED_P(p) ((uintptr_t) (p) % alignof (uint32_t) != 0)
if (UNALIGNED_P (buffer))
while (len > 64)
{
md4_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
buffer = (const char *) buffer + 64;
len -= 64;
}
else
#endif
{
md4_process_block (buffer, len & ~63, ctx);
buffer = (const char *) buffer + (len & ~63);
len &= 63;
}
}
/* Move remaining bytes in internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
memcpy (&((char*)ctx->buffer)[left_over], buffer, len);
left_over += len;
if (left_over >= 64)
{
md4_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
}
ctx->buflen = left_over;
}
}
/* --- Code below is the primary difference between md5.c and md4.c --- */
/* MD4 round constants */
#define K1 0x5a827999
#define K2 0x6ed9eba1
/* Round functions. */
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n))))
#define R1(a,b,c,d,k,s) a=rol(a+F(b,c,d)+x[k],s);
#define R2(a,b,c,d,k,s) a=rol(a+G(b,c,d)+x[k]+K1,s);
#define R3(a,b,c,d,k,s) a=rol(a+H(b,c,d)+x[k]+K2,s);
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 64 == 0. */
void
md4_process_block (const void *buffer, size_t len, struct md4_ctx *ctx)
{
const uint32_t *words = buffer;
size_t nwords = len / sizeof (uint32_t);
const uint32_t *endp = words + nwords;
uint32_t x[16];
uint32_t A = ctx->A;
uint32_t B = ctx->B;
uint32_t C = ctx->C;
uint32_t D = ctx->D;
/* First increment the byte count. RFC 1320 specifies the possible
length of the file up to 2^64 bits. Here we only compute the
number of bytes. Do a double word increment. */
ctx->total[0] += len;
if (ctx->total[0] < len)
++ctx->total[1];
/* Process all bytes in the buffer with 64 bytes in each round of
the loop. */
while (words < endp)
{
int t;
for (t = 0; t < 16; t++)
{
x[t] = SWAP (*words);
words++;
}
/* Round 1. */
R1 (A, B, C, D, 0, 3);
R1 (D, A, B, C, 1, 7);
R1 (C, D, A, B, 2, 11);
R1 (B, C, D, A, 3, 19);
R1 (A, B, C, D, 4, 3);
R1 (D, A, B, C, 5, 7);
R1 (C, D, A, B, 6, 11);
R1 (B, C, D, A, 7, 19);
R1 (A, B, C, D, 8, 3);
R1 (D, A, B, C, 9, 7);
R1 (C, D, A, B, 10, 11);
R1 (B, C, D, A, 11, 19);
R1 (A, B, C, D, 12, 3);
R1 (D, A, B, C, 13, 7);
R1 (C, D, A, B, 14, 11);
R1 (B, C, D, A, 15, 19);
/* Round 2. */
R2 (A, B, C, D, 0, 3);
R2 (D, A, B, C, 4, 5);
R2 (C, D, A, B, 8, 9);
R2 (B, C, D, A, 12, 13);
R2 (A, B, C, D, 1, 3);
R2 (D, A, B, C, 5, 5);
R2 (C, D, A, B, 9, 9);
R2 (B, C, D, A, 13, 13);
R2 (A, B, C, D, 2, 3);
R2 (D, A, B, C, 6, 5);
R2 (C, D, A, B, 10, 9);
R2 (B, C, D, A, 14, 13);
R2 (A, B, C, D, 3, 3);
R2 (D, A, B, C, 7, 5);
R2 (C, D, A, B, 11, 9);
R2 (B, C, D, A, 15, 13);
/* Round 3. */
R3 (A, B, C, D, 0, 3);
R3 (D, A, B, C, 8, 9);
R3 (C, D, A, B, 4, 11);
R3 (B, C, D, A, 12, 15);
R3 (A, B, C, D, 2, 3);
R3 (D, A, B, C, 10, 9);
R3 (C, D, A, B, 6, 11);
R3 (B, C, D, A, 14, 15);
R3 (A, B, C, D, 1, 3);
R3 (D, A, B, C, 9, 9);
R3 (C, D, A, B, 5, 11);
R3 (B, C, D, A, 13, 15);
R3 (A, B, C, D, 3, 3);
R3 (D, A, B, C, 11, 9);
R3 (C, D, A, B, 7, 11);
R3 (B, C, D, A, 15, 15);
A = ctx->A += A;
B = ctx->B += B;
C = ctx->C += C;
D = ctx->D += D;
}
}
+91
View File
@@ -0,0 +1,91 @@
/* Declarations of functions and data types used for MD4 sum
library functions.
Copyright (C) 2000-2001, 2003, 2005, 2008-2011 Free Software Foundation,
Inc.
This program 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 program 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; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef MD4_H
# define MD4_H 1
# include <stdio.h>
# include <stdint.h>
# ifdef __cplusplus
extern "C" {
# endif
# define MD4_DIGEST_SIZE 16
/* Structure to save state of computation between the single steps. */
struct md4_ctx
{
uint32_t A;
uint32_t B;
uint32_t C;
uint32_t D;
uint32_t total[2];
uint32_t buflen;
uint32_t buffer[32];
};
/* Initialize structure containing state of computation. */
extern void md4_init_ctx (struct md4_ctx *ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is necessary that LEN is a multiple of 64!!! */
extern void md4_process_block (const void *buffer, size_t len,
struct md4_ctx *ctx);
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is NOT required that LEN is a multiple of 64. */
extern void md4_process_bytes (const void *buffer, size_t len,
struct md4_ctx *ctx);
/* Process the remaining bytes in the buffer and put result from CTX
in first 16 bytes following RESBUF. The result is always in little
endian byte order, so that a byte-wise output yields to the wanted
ASCII representation of the message digest. */
extern void *md4_finish_ctx (struct md4_ctx *ctx, void *resbuf);
/* Put result from CTX in first 16 bytes following RESBUF. The result is
always in little endian byte order, so that a byte-wise output yields
to the wanted ASCII representation of the message digest. */
extern void *md4_read_ctx (const struct md4_ctx *ctx, void *resbuf);
/* Compute MD4 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 16 bytes
beginning at RESBLOCK. */
extern int md4_stream (FILE * stream, void *resblock);
/* Compute MD4 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
extern void *md4_buffer (const char *buffer, size_t len, void *resblock);
# ifdef __cplusplus
}
# endif
#endif