Skip to content
This repository has been archived by the owner on Dec 2, 2022. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
marczak committed Dec 4, 2015
0 parents commit c694904
Show file tree
Hide file tree
Showing 29 changed files with 1,907 additions and 0 deletions.
46 changes: 46 additions & 0 deletions Common/Common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/// Copyright 2015 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.

@import Foundation;
@import OpenDirectory;

///
/// Retrieves a mutable array from the plist on disk.
/// If the file doesn't exist or is unreadable, returns an empty mutable array.
///
NSMutableArray *GetUsers();

///
/// Writes out the provided array as a plist to disk.
///
void SetUsers(NSMutableArray *usersArray);

///
/// Validates that the provided password is the current user's login password.
///
BOOL ValidateLoginPassword(NSString *newPassword);

///
/// Validates that the provided password matches the password for the current user's
/// default keychain.
///
/// To attempt to avoid issues with the "Local Items" keychain, it makes a hardlink
/// to the keychain file with the date appended, opens that 'new' keychain file, attempts
/// to unlock it and then removes the hardlink. Attempting to unlock an unlocked keychain
/// will always succeed and locking the login keychain also locks the Local Items keychain
/// and so should be avoided.
///
/// Returns YES if password matches the keychain.
///
BOOL ValidateLoginKeychainPassword(NSString *OldPassword);
81 changes: 81 additions & 0 deletions Common/Common.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/// Copyright 2015 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.

#import "Common.h"

static NSString * const kPreferencePath =
@"/Library/Preferences/com.google.corp.keychainminder.plist";


NSMutableArray *GetUsers() {
NSMutableArray *currentUsers = [NSMutableArray arrayWithContentsOfFile:kPreferencePath];
return (currentUsers ? currentUsers : [NSMutableArray array]);
}

void SetUsers(NSMutableArray *usersArray) {
if (!usersArray) return;
[usersArray writeToFile:kPreferencePath atomically:YES];
}

BOOL ValidateLoginPassword(NSString *newPassword) {
NSError *err = nil;

ODSession *mySession = [ODSession defaultSession];

ODNode *myNode = [ODNode nodeWithSession:mySession type:kODNodeTypeAuthentication error:&err];
if (err) {
NSLog(@"Unable to get node: %@", err);
return NO;
}

ODRecord *myRecord = [myNode recordWithRecordType:kODRecordTypeUsers
name:NSUserName()
attributes:nil
error:&err];
if (err) {
NSLog(@"Unable to get %@'s record: %@", NSUserName(), err);
}

return [myRecord verifyPassword:newPassword error:nil];
}

BOOL ValidateLoginKeychainPassword(NSString *oldPassword) {
// Get default keychain path
SecKeychainRef defaultKeychain;
SecKeychainCopyDefault(&defaultKeychain);
UInt32 maxPathLen = MAXPATHLEN;
char keychainPath[MAXPATHLEN];
SecKeychainGetPath(defaultKeychain, &maxPathLen, keychainPath);
CFRelease(defaultKeychain);

// Duplicate the default keychain file to a new location.
NSString *path = @(keychainPath);
NSString *newPath = [path stringByAppendingFormat:@".%d",
(int)[[NSDate date] timeIntervalSince1970]];
if (link(path.UTF8String, newPath.UTF8String) != 0) {
return NO;
}

// Open and unlock this new keychain file.
SecKeychainRef keychainRef;
SecKeychainOpen(newPath.UTF8String, &keychainRef);
OSStatus err = SecKeychainUnlock(keychainRef, (UInt32)oldPassword.length,
oldPassword.UTF8String, YES);
CFRelease(keychainRef);

// Delete the temporary keychain file.
unlink(newPath.UTF8String);

return (err == errSecSuccess);
}
Binary file added Docs/KeychainMinderKnownPw.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/KeychainMinderUnknownPw.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/KeychainMinderWelcome.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit c694904

Please sign in to comment.