diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index 183e7ad5..cd7ec2bb 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -117,6 +117,7 @@ 4CE39ABF16ECE34A000FE29D /* MPIconSelectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE39ABE16ECE34A000FE29D /* MPIconSelectViewController.m */; }; 4CE39AC116ECE359000FE29D /* IconSelection.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CE39AC016ECE359000FE29D /* IconSelection.xib */; }; 4CE39AC416ECE4F7000FE29D /* MPPopupImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE39AC316ECE4F7000FE29D /* MPPopupImageView.m */; }; + 4CE5B54B173AFBA700207B39 /* MPDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5B549173AFBA700207B39 /* MPDocument.m */; }; 4CE8246F16E2E93400573141 /* MPOverlayWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE8246E16E2E93400573141 /* MPOverlayWindowController.m */; }; 4CE8247516E2F2B900573141 /* MPOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE8247416E2F2B900573141 /* MPOverlayView.m */; }; 4CFC53BF16E94729007396BE /* MPShadowBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFC53BE16E94729007396BE /* MPShadowBox.m */; }; @@ -321,6 +322,8 @@ 4CE39AC016ECE359000FE29D /* IconSelection.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IconSelection.xib; sourceTree = ""; }; 4CE39AC216ECE4F7000FE29D /* MPPopupImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPopupImageView.h; sourceTree = ""; }; 4CE39AC316ECE4F7000FE29D /* MPPopupImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPopupImageView.m; sourceTree = ""; }; + 4CE5B548173AFBA700207B39 /* MPDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDocument.h; sourceTree = ""; }; + 4CE5B549173AFBA700207B39 /* MPDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDocument.m; sourceTree = ""; }; 4CE8246D16E2E93400573141 /* MPOverlayWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayWindowController.h; sourceTree = ""; }; 4CE8246E16E2E93400573141 /* MPOverlayWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOverlayWindowController.m; sourceTree = ""; }; 4CE8247316E2F2B900573141 /* MPOverlayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayView.h; sourceTree = ""; }; @@ -425,6 +428,8 @@ 4CBA981615BA0DB600721965 /* MPDatabaseDocument.h */, 4CBA981715BA0DB600721965 /* MPDatabaseDocument.m */, 6E719715172058BA00E4C5FC /* MPDatabaseVersion.h */, + 4CE5B548173AFBA700207B39 /* MPDocument.h */, + 4CE5B549173AFBA700207B39 /* MPDocument.m */, ); name = Model; sourceTree = ""; @@ -962,6 +967,7 @@ 4C40AC5C170782730073D1C3 /* MPAbstractSettingsViewController.m in Sources */, 4C5A11FE1708DE8700223D8A /* MPPasswordCreatorViewController.m in Sources */, 4C7E832A172DE2F2002493D8 /* MPPasswordEditViewController.m in Sources */, + 4CE5B54B173AFBA700207B39 /* MPDocument.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MacPass/MPDatabaseDocument.m b/MacPass/MPDatabaseDocument.m index 76d68cd7..afff861e 100644 --- a/MacPass/MPDatabaseDocument.m +++ b/MacPass/MPDatabaseDocument.m @@ -109,7 +109,6 @@ NSString *const MPDidLoadDatabaseNotification = @"DidLoadDataBaseNotification"; return self; } - - (void)dealloc { self.tree = nil; diff --git a/MacPass/MPDocument.h b/MacPass/MPDocument.h new file mode 100644 index 00000000..25d9e133 --- /dev/null +++ b/MacPass/MPDocument.h @@ -0,0 +1,25 @@ +// +// MPDocument.h +// MacPass +// +// Created by Michael Starke on 08.05.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import +#import "MPDatabaseVersion.h" + +@class KdbGroup; + +@interface MPDocument : NSDocument + +@property (assign, readonly) KdbGroup *root; +@property (retain, readonly) NSURL *file; +@property (nonatomic,retain) NSString *password; +@property (nonatomic, retain) NSURL *key; +@property (assign, readonly) MPDatabaseVersion version; + +- (id)initWithVersion:(MPDatabaseVersion)version; +- (BOOL)decryptWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL; + +@end diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m new file mode 100644 index 00000000..ec41e617 --- /dev/null +++ b/MacPass/MPDocument.m @@ -0,0 +1,119 @@ +// +// MPDocument.m +// MacPass +// +// Created by Michael Starke on 08.05.13. +// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved. +// + +#import "MPDocument.h" +#import "KdbLib.h" +#import "Kdb3Node.h" +#import "Kdb4Node.h" +#import "KdbPassword.h" +#import "MPDatabaseVersion.h" + +@interface MPDocument () + +@property (retain) KdbTree *tree; +@property (retain) NSURL *file; +@property (nonatomic, readonly) KdbPassword *passwordHash; +@property (assign) MPDatabaseVersion version; + +@end + + +@implementation MPDocument + +- (id)init +{ + return [self initWithVersion:MPDatabaseVersion4]; +} + +- (id)initWithVersion:(MPDatabaseVersion)version { + self = [super init]; + if(self) { + switch(version) { + case MPDatabaseVersion3: + self.tree = [[[Kdb3Tree alloc] init] autorelease]; + break; + case MPDatabaseVersion4: + self.tree = [[[Kdb4Tree alloc] init] autorelease]; + break; + default: + [self release]; + return nil; + } + KdbGroup *newGroup = [self.tree createGroup:self.tree.root]; + newGroup.name = @"Default"; + } + return self; +} + +- (void) makeWindowControllers { +} + +- (NSString *)windowNibName +{ + // Override returning the nib file name of the document + // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead. + return @"MainWindow"; + //return @"MPDocument"; +} + +- (void)windowControllerDidLoadNib:(NSWindowController *)aController +{ + [super windowControllerDidLoadNib:aController]; + // Add any code here that needs to be executed once the windowController has loaded the document's window. +} + +- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError { + self.file = url; + + @try { + [KdbWriterFactory persist:self.tree file:[self.file path] withPassword:self.passwordHash]; + } + @catch (NSException *exception) { + NSLog(@"%@", [exception description]); + return NO; + } + + return YES; + +} + +- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError { + self.file = url; + return YES; +} + +- (BOOL)decryptWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL { + self.key = keyFileURL; + self.password = password; + @try { + self.tree = [KdbReaderFactory load:[self.file path] withPassword:self.passwordHash]; + } + @catch (NSException *exception) { + NSLog(@"%@", [exception description]); + return NO; + } + + if([self.tree isKindOfClass:[Kdb4Tree class]]) { + self.version = MPDatabaseVersion4; + } + else if( [self.tree isKindOfClass:[Kdb3Tree class]]) { + self.version = MPDatabaseVersion3; + } +} + +- (KdbPassword *)passwordHash { + // TODO: Use defaults to determine Encoding? + return [[[KdbPassword alloc] initWithPassword:self.password passwordEncoding:NSUTF8StringEncoding keyFile:[self.key path]] autorelease]; +} + ++ (BOOL)autosavesInPlace +{ + return NO; +} + +@end diff --git a/MacPass/MacPass-Info.plist b/MacPass/MacPass-Info.plist index b9480498..8d986e29 100644 --- a/MacPass/MacPass-Info.plist +++ b/MacPass/MacPass-Info.plist @@ -4,6 +4,29 @@ CFBundleDevelopmentRegion en + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + kdbx + + CFBundleTypeName + KeePass2 Database + CFBundleTypeRole + Editor + + + CFBundleTypeExtensions + + kdb + + CFBundleTypeName + KeePass Database + CFBundleTypeRole + Editor + + CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile @@ -21,7 +44,7 @@ CFBundleSignature ???? CFBundleVersion - 63A + 63C LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright