diff --git a/ChangeLog b/ChangeLog index e0fd7a001..8626fb3aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-12-29 Ludovic Marcotte + + * Moved the string encryption code from SoObjects/SOGo/SQLSource.m + to SoObjects/SOGo/NSString+Utilites.m + * SoObjects/SOGo/SOGoUserManager.m: We now store the passwords + in memcached as a SHA1 encrypted string. + 2010-12-28 Ludovic Marcotte * Implemented secured sessions. We no longer store in the diff --git a/SoObjects/SOGo/NSString+Utilities.h b/SoObjects/SOGo/NSString+Utilities.h index ab4199290..c98dca260 100644 --- a/SoObjects/SOGo/NSString+Utilities.h +++ b/SoObjects/SOGo/NSString+Utilities.h @@ -1,8 +1,9 @@ /* NSString+Utilities.h - this file is part of SOGo * - * Copyright (C) 2006 Inverse inc. + * Copyright (C) 2006-2011 Inverse inc. * * Author: Wolfgang Sourdeau + * Ludovic Marcotte * * 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 @@ -61,13 +62,17 @@ - (int) timeValue; -// LDIF - (BOOL) _isLDIFSafe; - (BOOL) isJSONString; - (id) objectFromJSONString; +- (NSString *) asCryptString; +- (NSString *) asMD5String; +- (NSString *) asSHA1String; + + @end #endif /* NSSTRING_URL_H */ diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index df13789e8..6856c11c0 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -1,8 +1,9 @@ /* NSString+Utilities.m - this file is part of SOGo * - * Copyright (C) 2006-2009 Inverse inc. + * Copyright (C) 2006-2011 Inverse inc. * * Author: Wolfgang Sourdeau + * Ludovic Marcotte * * 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 @@ -39,6 +40,12 @@ #import "NSString+Utilities.h" +#define _XOPEN_SOURCE 1 +#include +#include +#include +#include + static NSMutableCharacterSet *urlNonEndingChars = nil; static NSMutableCharacterSet *urlAfterEndingChars = nil; static NSMutableCharacterSet *urlStartChars = nil; @@ -538,4 +545,47 @@ static NSMutableCharacterSet *safeLDIFStartChars = nil; return object; } +- (NSString *) asCryptString +{ + char *buf; + + // The salt is weak here, but who cares anyway, crypt should not + // be used anymore + buf = (char *)crypt([self UTF8String], [self UTF8String]); + return [NSString stringWithUTF8String: buf]; +} + +- (NSString *) asMD5String +{ + unsigned char md[MD5_DIGEST_LENGTH]; + char buf[80]; + int i; + + memset(md, 0, MD5_DIGEST_LENGTH); + memset(buf, 0, 80); + + EVP_Digest((const void *) [self UTF8String], strlen([self UTF8String]), md, NULL, EVP_md5(), NULL); + for (i = 0; i < MD5_DIGEST_LENGTH; i++) + sprintf(&(buf[i*2]), "%02x", md[i]); + + return [NSString stringWithUTF8String: buf]; +} + +- (NSString *) asSHA1String +{ + unsigned char sha[SHA_DIGEST_LENGTH]; + char buf[80]; + int i; + + memset(sha, 0, SHA_DIGEST_LENGTH); + memset(buf, 0, 80); + + SHA1((const void *)[self UTF8String], strlen([self UTF8String]), sha); + for (i = 0; i < SHA_DIGEST_LENGTH; i++) + sprintf(&(buf[i*2]), "%02x", sha[i]); + + return [NSString stringWithUTF8String: buf]; +} + + @end diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 4c463492c..fdbfa34d9 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -422,7 +422,10 @@ currentUser = [jsonUser objectFromJSONString]; dictPassword = [currentUser objectForKey: @"password"]; if (currentUser && dictPassword) - checkOK = ([dictPassword isEqualToString: _pwd]); + { + checkOK = ([dictPassword isEqualToString: [_pwd asSHA1String]]); + //NSLog(@"Password cache hit for user %@", _login); + } else if ([self _sourceCheckLogin: _login andPassword: _pwd perr: _perr @@ -440,7 +443,7 @@ // set the password and recache the entry, the password would never be // cached for the user unless its entry expires from memcached's // internal cache. - [currentUser setObject: _pwd forKey: @"password"]; + [currentUser setObject: [_pwd asSHA1String] forKey: @"password"]; [[SOGoCache sharedCache] setUserAttributes: [currentUser jsonRepresentation] forLogin: _login]; @@ -500,7 +503,7 @@ // set the password and recache the entry, the password would never be // cached for the user unless its entry expires from memcached's // internal cache. - [currentUser setObject: newPassword forKey: @"password"]; + [currentUser setObject: [newPassword asSHA1String] forKey: @"password"]; [[SOGoCache sharedCache] setUserAttributes: [currentUser jsonRepresentation] forLogin: login]; diff --git a/SoObjects/SOGo/SQLSource.m b/SoObjects/SOGo/SQLSource.m index 9996315e1..1ddf7e63e 100644 --- a/SoObjects/SOGo/SQLSource.m +++ b/SoObjects/SOGo/SQLSource.m @@ -20,13 +20,6 @@ * Boston, MA 02111-1307, USA. */ -#define _XOPEN_SOURCE 1 -#include - -#include -#include -#include - #import #import #import @@ -43,6 +36,7 @@ #import #import "SOGoConstants.h" +#import "NSString+Utilities.h" #import "SQLSource.h" @@ -145,49 +139,16 @@ } else if ([_userPasswordAlgorithm caseInsensitiveCompare: @"crypt"] == NSOrderedSame) { - NSString *s; - char *buf; - - buf = (char *)crypt([plainPassword UTF8String], [encryptedPassword UTF8String]); - s = [NSString stringWithUTF8String: buf]; - - return [s isEqualToString: encryptedPassword]; + return [[plainPassword asCryptString] isEqualToString: encryptedPassword]; } else if ([_userPasswordAlgorithm caseInsensitiveCompare: @"md5"] == NSOrderedSame) { - NSString *s; - - unsigned char md[MD5_DIGEST_LENGTH]; - char buf[80]; - int i; - - memset(md, 0, MD5_DIGEST_LENGTH); - memset(buf, 0, 80); - - EVP_Digest((const void *) [plainPassword UTF8String], strlen([plainPassword UTF8String]), md, NULL, EVP_md5(), NULL); - for (i = 0; i < MD5_DIGEST_LENGTH; i++) - sprintf(&(buf[i*2]), "%02x", md[i]); - - s = [NSString stringWithUTF8String: buf]; - return [s isEqualToString: encryptedPassword]; + return [[plainPassword asMD5String] isEqualToString: encryptedPassword]; } else if ([_userPasswordAlgorithm caseInsensitiveCompare: @"sha"] == NSOrderedSame) { - NSString *s; - unsigned char sha[SHA_DIGEST_LENGTH]; - char buf[80]; - int i; - - memset(sha, 0, SHA_DIGEST_LENGTH); - memset(buf, 0, 80); - - SHA1((const void *)[plainPassword UTF8String], strlen([plainPassword UTF8String]), sha); - for (i = 0; i < SHA_DIGEST_LENGTH; i++) - sprintf(&(buf[i*2]), "%02x", sha[i]); - - s = [NSString stringWithUTF8String: buf]; - return [s isEqualToString: encryptedPassword]; + return [[plainPassword asSHA1String] isEqualToString: encryptedPassword]; }