Revision: 2911
http://skim-app.svn.sourceforge.net/skim-app/?rev=2911&view=rev
Author: hofman
Date: 2007-09-12 12:05:23 -0700 (Wed, 12 Sep 2007)
Log Message:
-----------
Save password in keychain, after showing an alert when a password was entered
successfully. Use a hack: override a method of the private PDFDisplayView class.
Modified Paths:
--------------
trunk/SKDocument.h
trunk/SKPDFView.m
trunk/Skim.xcodeproj/project.pbxproj
Modified: trunk/SKDocument.h
===================================================================
--- trunk/SKDocument.h 2007-09-12 16:35:19 UTC (rev 2910)
+++ trunk/SKDocument.h 2007-09-12 19:05:23 UTC (rev 2911)
@@ -105,6 +105,8 @@
- (NSString *)notesFDFString;
- (NSString *)notesFDFStringForFile:(NSString *)filename;
+- (NSArray *)fileIDStrings;
+
- (NSDictionary *)currentDocumentSetup;
- (SKPDFSynchronizer *)synchronizer;
Modified: trunk/SKPDFView.m
===================================================================
--- trunk/SKPDFView.m 2007-09-12 16:35:19 UTC (rev 2910)
+++ trunk/SKPDFView.m 2007-09-12 19:05:23 UTC (rev 2911)
@@ -56,6 +56,8 @@
#import <Carbon/Carbon.h>
#import "NSGeometry_SKExtensions.h"
#import "SKTypeSelectHelper.h"
+#import "OBUtilities.h"
+#import <Security/Security.h>
NSString *SKPDFViewToolModeChangedNotification =
@"SKPDFViewToolModeChangedNotification";
NSString *SKPDFViewAnnotationModeChangedNotification =
@"SKPDFViewAnnotationModeChangedNotification";
@@ -115,6 +117,8 @@
- (NSCursor *)cursorForEvent:(NSEvent *)theEvent;
- (void)updateCursor;
+- (void)tryToUnlockDocument:(PDFDocument *)document;
+
@end
#pragma mark -
@@ -449,6 +453,8 @@
#pragma mark Accessors
- (void)setDocument:(PDFDocument *)document {
+ if ([document isLocked] && [[NSUserDefaults standardUserDefaults]
boolForKey:@"SKDisableSavingPassword"] == NO)
+ [self tryToUnlockDocument:document];
[readingBar release];
readingBar = nil;
selectionRect = NSZeroRect;
@@ -3678,6 +3684,26 @@
[[self cursorForEvent:event] set];
}
+- (void)tryToUnlockDocument:(PDFDocument *)document {
+ NSArray *fileIDStrings = [(SKDocument *)[[[self window] windowController]
document] fileIDStrings];
+ NSString *fileIDString = [fileIDStrings count] ? [fileIDStrings
objectAtIndex:0] : nil;
+ if (fileIDString) {
+ const char *serviceName = [[NSString stringWithFormat:@"Skim - %@",
fileIDString] UTF8String];
+ const char *userName = [NSUserName() UTF8String];
+ void *passwordData = NULL;
+ UInt32 passwordLength = 0;
+ NSData *data = nil;
+ NSString *password = nil;
+ OSErr err = SecKeychainFindGenericPassword(NULL, strlen(serviceName),
serviceName, strlen(userName), userName, &passwordLength, &passwordData, NULL);
+ if (err == noErr) {
+ data = [NSData dataWithBytes:passwordData length:passwordLength];
+ SecKeychainItemFreeContent(NULL, passwordData);
+ password = [[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding] autorelease];
+ [document unlockWithPassword:password];
+ }
+ }
+}
+
@end
#pragma mark Core Graphics extension
@@ -3760,3 +3786,77 @@
@end
+#pragma mark -
+
[EMAIL PROTECTED] PDFDisplayView : NSView
+- (void)passwordEntered:(id)sender;
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] PDFDisplayView (SKExtensions)
+- (void)replacementPasswordEntered:(id)sender;
+- (void)savePasswordInKeychain:(NSString *)password;
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] PDFDisplayView (SKExtensions)
+
+static IMP originalPasswordEntered = NULL;
+
++ (void)load {
+ if ([self instancesRespondToSelector:@selector(passwordEntered:)])
+ originalPasswordEntered =
OBReplaceMethodImplementationWithSelector(self, @selector(passwordEntered:),
@selector(replacementPasswordEntered:));
+}
+
+- (void)replacementPasswordEntered:(id)sender {
+ originalPasswordEntered(self, _cmd, sender);
+ if ([[NSUserDefaults standardUserDefaults]
boolForKey:@"SKDisableSavingPassword"] == NO) {
+ SKDocument *document = [[[self window] windowController] document];
+ if ([document isKindOfClass:[SKDocument class]] && [[document
pdfDocument] isLocked] == NO)
+ [self savePasswordInKeychain:[sender stringValue]];
+ }
+}
+
+- (void)savePasswordInKeychain:(NSString *)password {
+ SKDocument *document = [[[self window] windowController] document];
+ NSArray *fileIDStrings = [document fileIDStrings];
+ NSString *fileIDString = [fileIDStrings count] ? [fileIDStrings
objectAtIndex:0] : nil;
+ if (fileIDString) {
+ NSAlert *alert = [NSAlert alertWithMessageText:[NSString
stringWithFormat:NSLocalizedString(@"Remember Password?", @"Message in alert
dialog")]
+
defaultButton:NSLocalizedString(@"Yes", @"Button title")
+
alternateButton:NSLocalizedString(@"No", @"Button title")
+ otherButton:nil
+ informativeTextWithFormat:NSLocalizedString(@"Do
you want to save this password in your Keychain?", @"Informative text in alert
dialog")];
+ if ([alert runModal] == NSAlertDefaultReturn) {
+ const char *userNameCString = [NSUserName() UTF8String];
+ const char *nameCString = [[NSString stringWithFormat:@"Skim -
%@", fileIDString] UTF8String];
+
+ OSStatus err;
+ SecKeychainItemRef itemRef = NULL;
+ const void *passwordData = NULL;
+ UInt32 passwordLength = 0;
+
+ // first see if the password exists in the keychain
+ err = SecKeychainFindGenericPassword(NULL, strlen(nameCString),
nameCString, strlen(userNameCString), userNameCString, &passwordLength, (void
**)&passwordData, &itemRef);
+
+ if(err == noErr){
+ // password was on keychain, so flush the buffer and then
modify the keychain
+ SecKeychainItemFreeContent(NULL, (void *)passwordData);
+ passwordData = NULL;
+
+ passwordData = [password UTF8String];
+ SecKeychainAttribute attrs[] = {
+ { kSecAccountItemAttr, strlen(userNameCString), (char
*)userNameCString },
+ { kSecServiceItemAttr, strlen(nameCString), (char
*)nameCString } };
+ const SecKeychainAttributeList attributes = { sizeof(attrs) /
sizeof(attrs[0]), attrs };
+
+ err = SecKeychainItemModifyAttributesAndData(itemRef,
&attributes, strlen(passwordData), passwordData);
+ } else if(err == errSecItemNotFound){
+ // password not on keychain, so add it
+ passwordData = [password UTF8String];
+ err = SecKeychainAddGenericPassword(NULL, strlen(nameCString),
nameCString, strlen(userNameCString), userNameCString, strlen(passwordData),
passwordData, &itemRef);
+ } else
+ NSLog(@"Error %d occurred setting password", err);
+ }
+ }
+}
+
[EMAIL PROTECTED]
Modified: trunk/Skim.xcodeproj/project.pbxproj
===================================================================
--- trunk/Skim.xcodeproj/project.pbxproj 2007-09-12 16:35:19 UTC (rev
2910)
+++ trunk/Skim.xcodeproj/project.pbxproj 2007-09-12 19:05:23 UTC (rev
2911)
@@ -150,6 +150,7 @@
CE9C423C0B8B5633004AD8CF /* PreferenceWindow.nib in Resources
*/ = {isa = PBXBuildFile; fileRef = CE9C42360B8B5633004AD8CF /*
PreferenceWindow.nib */; };
CE9DC2EA0B9F131900D64F28 /* ToolbarHighlightNote.tiff in
Resources */ = {isa = PBXBuildFile; fileRef = CE9DC2E80B9F131800D64F28 /*
ToolbarHighlightNote.tiff */; };
CEA182280C92E3300061A6D4 /* NSData_SKExtensions.m in Sources */
= {isa = PBXBuildFile; fileRef = CEA182260C92E3300061A6D4 /*
NSData_SKExtensions.m */; };
+ CEA1CD1B0C9864470061A6D4 /* Security.framework in Frameworks */
= {isa = PBXBuildFile; fileRef = CEA1CCE60C9864470061A6D4 /* Security.framework
*/; };
CEA575CE0B9206E60003D2E7 /* SKNoteOutlineView.m in Sources */ =
{isa = PBXBuildFile; fileRef = CEA575CD0B9206E60003D2E7 /* SKNoteOutlineView.m
*/; };
CEA575E50B9207B80003D2E7 /* SKThumbnailTableView.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CEA575E40B9207B80003D2E7 /*
SKThumbnailTableView.m */; };
CEA575FD0B9208B60003D2E7 /* SKTocOutlineView.m in Sources */ =
{isa = PBXBuildFile; fileRef = CEA575FC0B9208B60003D2E7 /* SKTocOutlineView.m
*/; };
@@ -531,6 +532,7 @@
CE9DC2E80B9F131800D64F28 /* ToolbarHighlightNote.tiff */ = {isa
= PBXFileReference; lastKnownFileType = image.tiff; name =
ToolbarHighlightNote.tiff; path = Images/ToolbarHighlightNote.tiff; sourceTree
= "<group>"; };
CEA182250C92E3300061A6D4 /* NSData_SKExtensions.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
NSData_SKExtensions.h; sourceTree = "<group>"; };
CEA182260C92E3300061A6D4 /* NSData_SKExtensions.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= NSData_SKExtensions.m; sourceTree = "<group>"; };
+ CEA1CCE60C9864470061A6D4 /* Security.framework */ = {isa =
PBXFileReference; lastKnownFileType = wrapper.framework; name =
Security.framework; path = /System/Library/Frameworks/Security.framework;
sourceTree = "<absolute>"; };
CEA575CC0B9206E60003D2E7 /* SKNoteOutlineView.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SKNoteOutlineView.h; sourceTree = "<group>"; };
CEA575CD0B9206E60003D2E7 /* SKNoteOutlineView.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= SKNoteOutlineView.m; sourceTree = "<group>"; };
CEA575E30B9207B80003D2E7 /* SKThumbnailTableView.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SKThumbnailTableView.h; sourceTree = "<group>"; };
@@ -644,6 +646,7 @@
CE2BD83E0BD4132B00A5F4DB /* Sparkle.framework
in Frameworks */,
CE5F43730BF8A3410069D89C /* IOKit.framework in
Frameworks */,
CE1ADB280C4BC6DE00071840 /* OpenGL.framework in
Frameworks */,
+ CEA1CD1B0C9864470061A6D4 /* Security.framework
in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -662,6 +665,7 @@
1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
+ CEA1CCE60C9864470061A6D4 /* Security.framework
*/,
1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */,
F98E24BE0B702D9400914AF0 /* Carbon.framework */,
455989F70B2662FF00E5419B /* Quartz.framework */,
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit