Skip to content
This repository was archived by the owner on Jan 30, 2018. It is now read-only.

updated a lot - I think it still all works #57

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Next Next commit
Drop support for 10.6-era ShadowHash file; add 10.8+ ShadowHashData a…
…nd AuthenticationAuthority to user account plist
  • Loading branch information
gregneagle committed Jun 20, 2017
commit 8426ca288713e3cae764c8fff3a3df715b691a9c
23 changes: 12 additions & 11 deletions CreateUserPkg.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@
6605E696159B964D0048362A /* CUPUserNameFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6605E692159B964D0048362A /* CUPUserNameFormatter.m */; };
6605E697159B964D0048362A /* CUPUUIDFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6605E694159B964D0048362A /* CUPUUIDFormatter.m */; };
66B221D8159C4C30003FDF4E /* CreateUserPkg.icns in Resources */ = {isa = PBXBuildFile; fileRef = 66B221D7159C4C30003FDF4E /* CreateUserPkg.icns */; };
C09EAB201EF8EDFE005A8859 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C09EAB1F1EF8EDFE005A8859 /* Security.framework */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
@@ -58,13 +59,15 @@
6605E693159B964D0048362A /* CUPUUIDFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CUPUUIDFormatter.h; sourceTree = "<group>"; };
6605E694159B964D0048362A /* CUPUUIDFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CUPUUIDFormatter.m; sourceTree = "<group>"; };
66B221D7159C4C30003FDF4E /* CreateUserPkg.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = CreateUserPkg.icns; sourceTree = "<group>"; };
C09EAB1F1EF8EDFE005A8859 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = ../../../../System/Library/Frameworks/Security.framework; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
0596D175159AF27800B898B4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C09EAB201EF8EDFE005A8859 /* Security.framework in Frameworks */,
0596D17D159AF27800B898B4 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -102,6 +105,7 @@
0596D17E159AF27800B898B4 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
C09EAB1F1EF8EDFE005A8859 /* Security.framework */,
0596D17F159AF27800B898B4 /* AppKit.framework */,
0596D180159AF27800B898B4 /* CoreData.framework */,
0596D181159AF27800B898B4 /* Foundation.framework */,
@@ -180,11 +184,6 @@
CLASSPREFIX = CUP;
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = "University of Gothenburg";
TargetAttributes = {
0596D177159AF27800B898B4 = {
DevelopmentTeam = 5KQ3D3FG5H;
};
};
};
buildConfigurationList = 0596D172159AF27800B898B4 /* Build configuration list for PBXProject "CreateUserPkg" */;
compatibilityVersion = "Xcode 3.2";
@@ -377,13 +376,14 @@
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = CreateUserPkg/CreateUserPkg.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer";
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "CreateUserPkg/CreateUserPkg-Prefix.pch";
INFOPLIST_FILE = "CreateUserPkg/CreateUserPkg-Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_BUNDLE_IDENTIFIER = "se.gu.it.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
@@ -396,13 +396,14 @@
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = CreateUserPkg/CreateUserPkg.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer";
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "CreateUserPkg/CreateUserPkg-Prefix.pch";
INFOPLIST_FILE = "CreateUserPkg/CreateUserPkg-Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_BUNDLE_IDENTIFIER = "se.gu.it.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
3 changes: 3 additions & 0 deletions CreateUserPkg/CUPDocument.h
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
NSTextField *__unsafe_unretained _version;

NSMutableString *_shadowHash;
NSData *_shadowHashData;
NSData *_kcPassword;
NSMutableDictionary *_docState;
}
@@ -50,13 +51,15 @@
@property (unsafe_unretained) IBOutlet NSTextField *version;

@property (strong) NSMutableString *shadowHash;
@property (strong) NSData *shadowHashData;
@property (strong) NSData *kcPassword;
@property (strong) NSMutableDictionary *docState;

- (IBAction)didLeaveFullName:(id)sender;
- (IBAction)didLeaveAccountName:(id)sender;
- (IBAction)didLeavePassword:(id)sender;

- (void)calculateShadowHashData:(NSString *)pwd;
- (void)calculateShadowHash:(NSString *)pwd;
- (void)calculateKCPassword:(NSString *)pwd;
- (void)setTextField:(NSTextField *)field withKey:(NSString *)key;
35 changes: 35 additions & 0 deletions CreateUserPkg/CUPDocument.m
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@
//

#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonKeyDerivation.h>
#import <Security/Security.h>
#import "CUPDocument.h"
#import "CUPUIDFormatter.h"
#import "CUPUserNameFormatter.h"
@@ -31,6 +33,7 @@ @implementation CUPDocument
@synthesize version = _version;

@synthesize shadowHash = _shadowHash;
@synthesize shadowHashData = _shadowHashData;
@synthesize kcPassword = _kcPassword;
@synthesize docState = _docState;

@@ -99,8 +102,38 @@ - (IBAction)didLeavePassword:(id)sender {
}
}


- (void)calculateShadowHashData:(NSString *)pwd
{
unsigned char salt[32];
int status = SecRandomCopyBytes(kSecRandomDefault, 32, salt);
unsigned char key[128];
unsigned int rounds = 400000;
CCKeyDerivationPBKDF(kCCPBKDF2,
[pwd UTF8String],
(CC_LONG)[pwd lengthOfBytesUsingEncoding:NSUTF8StringEncoding],
salt, 32,
kCCPRFHmacAlgSHA512, rounds, key, 128);
NSDictionary *dictionary = @{
@"SALTED-SHA512-PBKDF2" : @{
@"entropy" : [NSData dataWithBytes: key length: 128],
@"iterations" : [NSNumber numberWithUnsignedInt: rounds],
@"salt" : [NSData dataWithBytes: salt length: 32]
}
};
NSError * _Nullable __autoreleasing * error = NULL;
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList: dictionary
format: NSPropertyListBinaryFormat_v1_0
options: 0
error: error];
self.shadowHashData = plistData;
//NSLog(@"ShadowHashData: %@", plistData);
}


- (void)calculateShadowHash:(NSString *)pwd
{
[self calculateShadowHashData:pwd];
CC_SHA1_CTX ctx;
unsigned char salted_sha1_hash[24];
union _salt {
@@ -296,6 +329,7 @@ - (BOOL)validateDocumentAndUpdateState
[self calculateShadowHash:[self.password stringValue]];
}
(self.docState)[@"shadowHash"] = [NSString stringWithString:self.shadowHash];
(self.docState)[@"shadowHashData"] = self.shadowHashData;
}
if ([self.automaticLogin state] == NSOnState) {
if ([self.kcPassword length] == 0) {
@@ -374,6 +408,7 @@ - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError *
[self setDocStateKey:@"packageID" fromDict:document];
[self setDocStateKey:@"version" fromDict:document];
[self setDocStateKey:@"shadowHash" fromDict:document];
[self setDocStateKey:@"shadowHashData" fromDict:document];
[self setDocStateKey:@"imageData" fromDict:document];
[self setDocStateKey:@"imagePath" fromDict:document];
[self setDocStateKey:@"kcPassword" fromDict:document];
17 changes: 4 additions & 13 deletions CreateUserPkg/create_package.py
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
REQUIRED_KEYS = set((
u"fullName",
u"accountName",
u"shadowHash",
u"shadowHashData",
u"userID",
u"isAdmin",
u"homeDirectory",
@@ -219,7 +219,8 @@ def main(argv):

# Create a dictionary with user attributes.
user_plist = dict()
user_plist[u"authentication_authority"] = [u";ShadowHash;"]
user_plist[u"authentication_authority"] = [u";ShadowHash;HASHLIST:<SALTED-SHA512-PBKDF2>"]
user_plist[u"ShadowHashData"] = [input_data[u"shadowHashData"]]
user_plist[u"generateduid"] = [input_data[u"uuid"]]
user_plist[u"gid"] = [u"20"]
user_plist[u"home"] = [input_data[u"homeDirectory"]]
@@ -251,7 +252,7 @@ def main(argv):
kcpassword = None
is_admin = input_data.get(u"isAdmin", False)

# Create a package with the plist for our user and a shadow hash file.
# Create a package with the plist for our user.
tmp_path = tempfile.mkdtemp()
try:
# Create a root for the package.
@@ -260,7 +261,6 @@ def main(argv):
# Create package structure inside root.
os.makedirs(os.path.join(pkg_root_path, "private/var/db/dslocal/nodes"), 0755)
os.makedirs(os.path.join(pkg_root_path, "private/var/db/dslocal/nodes/Default/users"), 0700)
os.makedirs(os.path.join(pkg_root_path, "private/var/db/shadow/hash"), 0700)
if kcpassword:
os.makedirs(os.path.join(pkg_root_path, "private/etc"), 0755)
# Save user plist.
@@ -270,15 +270,6 @@ def main(argv):
user_plist_name)
plistlib.writePlist(user_plist, user_plist_path)
os.chmod(user_plist_path, 0600)
# Save shadow hash.
shadow_hash_name = input_data[u"uuid"]
shadow_hash_path = os.path.join(pkg_root_path,
"private/var/db/shadow/hash",
shadow_hash_name)
f = open(shadow_hash_path, "w")
f.write(shadow_hash)
f.close()
os.chmod(shadow_hash_path, 0600)
# Save kcpassword.
if kcpassword:
kcpassword_path = os.path.join(pkg_root_path, "private/etc/kcpassword")