2
0

Make new site creation on Mac same as iOS.

[FIXED]     Unable to create a site that is a substring of an existing site.
This commit is contained in:
Maarten Billemont 2015-03-05 17:28:04 -05:00
parent ca8f14fd3e
commit a383d0eee7
4 changed files with 139 additions and 65 deletions

View File

@ -80,7 +80,7 @@ uint8_t const *mpw_scrypt(const size_t keySize, const char *secret, const uint8_
uint8_t const *mpw_hmac_sha256(const uint8_t *key, const size_t keySize, const uint8_t *salt, const size_t saltSize) { uint8_t const *mpw_hmac_sha256(const uint8_t *key, const size_t keySize, const uint8_t *salt, const size_t saltSize) {
uint8_t *const buffer = malloc(32); uint8_t *const buffer = malloc( 32 );
if (!buffer) if (!buffer)
return NULL; return NULL;
@ -96,24 +96,29 @@ const char *mpw_idForBuf(const void *buf, size_t length) {
return mpw_hex( hash, 32 ); return mpw_hex( hash, 32 );
} }
static char **mpw_hex_buf = NULL; //static char **mpw_hex_buf = NULL;
static unsigned int mpw_hex_buf_i = 0; //static unsigned int mpw_hex_buf_i = 0;
const char *mpw_hex(const void *buf, size_t length) { const char *mpw_hex(const void *buf, size_t length) {
if (!mpw_hex_buf) { // FIXME
mpw_hex_buf = malloc( 10 * sizeof( char* ) ); // if (!mpw_hex_buf) {
for (uint8_t i = 0; i < 10; ++i) // mpw_hex_buf = malloc( 10 * sizeof( char * ) );
mpw_hex_buf[i] = NULL; // for (uint8_t i = 0; i < 10; ++i)
} // mpw_hex_buf[i] = NULL;
mpw_hex_buf_i = (mpw_hex_buf_i + 1) % 10; // }
// mpw_hex_buf_i = (mpw_hex_buf_i + 1) % 10;
//
// mpw_hex_buf[mpw_hex_buf_i] = realloc( mpw_hex_buf[mpw_hex_buf_i], length * 2 + 1 );
// for (size_t kH = 0; kH < length; kH++)
// sprintf( &(mpw_hex_buf[mpw_hex_buf_i][kH * 2]), "%02X", ((const uint8_t *)buf)[kH] );
mpw_hex_buf[mpw_hex_buf_i] = realloc( mpw_hex_buf[mpw_hex_buf_i], length * 2 + 1 ); // return mpw_hex_buf[mpw_hex_buf_i];
for (size_t kH = 0; kH < length; kH++) return NULL;
sprintf( &(mpw_hex_buf[mpw_hex_buf_i][kH * 2]), "%02X", ((const uint8_t *)buf)[kH] );
return mpw_hex_buf[mpw_hex_buf_i];
} }
const char *mpw_hex_l(uint32_t number) { const char *mpw_hex_l(uint32_t number) {
return mpw_hex( &number, sizeof( number ) ); return mpw_hex( &number, sizeof( number ) );
} }
@ -144,7 +149,8 @@ const char *mpw_identicon(const char *fullName, const char *masterPassword) {
const char *accessory[] = { const char *accessory[] = {
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }; "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
};
uint8_t identiconSeed[32]; uint8_t identiconSeed[32];
HMAC_SHA256_Buf( masterPassword, strlen( masterPassword ), fullName, strlen( fullName ), identiconSeed ); HMAC_SHA256_Buf( masterPassword, strlen( masterPassword ), fullName, strlen( fullName ), identiconSeed );
@ -206,8 +212,8 @@ const size_t mpw_charlen(const char *utf8String) {
size_t charlen = 0; size_t charlen = 0;
char *remainingString = (char *)utf8String; char *remainingString = (char *)utf8String;
for (int charByteSize; (charByteSize = mpw_charByteSize( *remainingString )); remainingString += charByteSize) for (int charByteSize; (charByteSize = mpw_charByteSize( (unsigned char)*remainingString )); remainingString += charByteSize)
++charlen; ++charlen;
return charlen; return charlen;
} }

View File

@ -463,26 +463,26 @@
- (void)useSite { - (void)useSite {
MPSiteModel *selectedSite = [self selectedSite]; MPSiteModel *selectedSite = [self selectedSite];
if (selectedSite) { if (!selectedSite)
// Performing action while content is available. Copy it. return;
[self copyContent:selectedSite.content];
[self fadeOut]; if (selectedSite.transient) {
[self createNewSite:selectedSite.name];
return;
}
NSUserNotification *notification = [NSUserNotification new]; // Performing action while content is available. Copy it.
notification.title = @"Password Copied"; [self copyContent:selectedSite.content];
if (selectedSite.loginName.length)
notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.name ); [self fadeOut];
else
notification.subtitle = selectedSite.name; NSUserNotification *notification = [NSUserNotification new];
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; notification.title = @"Password Copied";
} if (selectedSite.loginName.length)
else { notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.name );
NSString *siteName = [self.siteField stringValue]; else
if ([siteName length]) notification.subtitle = selectedSite.name;
// Performing action without content but a site name is written. [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
[self createNewSite:siteName];
}
} }
- (void)updateUser { - (void)updateUser {
@ -549,9 +549,15 @@
return; return;
} }
BOOL exact = NO;
NSMutableArray *newSites = [NSMutableArray arrayWithCapacity:[siteResults count]]; NSMutableArray *newSites = [NSMutableArray arrayWithCapacity:[siteResults count]];
for (MPSiteEntity *site in siteResults) for (MPSiteEntity *site in siteResults) {
[newSites addObject:[[MPSiteModel alloc] initWithEntity:site fuzzyGroups:fuzzyGroups]]; [newSites addObject:[[MPSiteModel alloc] initWithEntity:site fuzzyGroups:fuzzyGroups]];
exact |= [site.name isEqualToString:queryString];
}
if (!exact && [queryString length])
[newSites addObject:[[MPSiteModel alloc] initWithName:queryString]];
dbg( @"newSites: %@", newSites );
self.sites = newSites; self.sites = newSites;
}]; }];
} }

View File

@ -35,10 +35,12 @@
@property (nonatomic) NSUInteger counter; @property (nonatomic) NSUInteger counter;
@property (nonatomic) NSDate *lastUsed; @property (nonatomic) NSDate *lastUsed;
@property (nonatomic) id<MPAlgorithm> algorithm; @property (nonatomic) id<MPAlgorithm> algorithm;
@property (nonatomic) BOOL generated; @property (nonatomic, readonly) BOOL generated;
@property (nonatomic) BOOL stored; @property (nonatomic, readonly) BOOL stored;
@property (nonatomic, readonly) BOOL transient;
- (instancetype)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups; - (instancetype)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups;
- (instancetype)initWithName:(NSString *)siteName;
- (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc; - (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc;
- (void)updateContent; - (void)updateContent;

View File

@ -28,7 +28,7 @@
BOOL _initialized; BOOL _initialized;
} }
- (id)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups { - (instancetype)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
if (!(self = [super init])) if (!(self = [super init]))
return nil; return nil;
@ -39,6 +39,17 @@
return self; return self;
} }
- (instancetype)initWithName:(NSString *)siteName {
if (!(self = [super init]))
return nil;
[self setTransientSiteName:siteName];
_initialized = YES;
return self;
}
- (void)setEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups { - (void)setEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
if ([_entityOID isEqual:entity.objectID]) if ([_entityOID isEqual:entity.objectID])
@ -73,6 +84,28 @@
[self updateContent:entity]; [self updateContent:entity];
} }
- (void)setTransientSiteName:(NSString *)siteName {
_entityOID = nil;
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.alignment = NSCenterTextAlignment;
self.displayedName = stra( siteName, @{
NSBackgroundColorAttributeName : [NSColor alternateSelectedControlColor],
NSParagraphStyleAttributeName : paragraphStyle,
} );
self.name = siteName;
self.algorithm = MPAlgorithmDefault;
self.lastUsed = nil;
self.type = [MPAppDelegate_Shared get].activeUserForMainThread.defaultType;
self.typeName = [self.algorithm nameOfType:self.type];
self.uses = @0;
self.counter = 1;
// Find all password types and the index of the current type amongst them.
[self updateContent];
}
- (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc { - (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc {
if (!_entityOID) if (!_entityOID)
@ -96,15 +129,18 @@
// This wasn't a change to the entity. // This wasn't a change to the entity.
return; return;
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { if (_entityOID)
MPSiteEntity *entity = [self entityInContext:context]; [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
if ([entity isKindOfClass:[MPGeneratedSiteEntity class]]) { MPSiteEntity *entity = [self entityInContext:context];
((MPGeneratedSiteEntity *)entity).counter = counter; if ([entity isKindOfClass:[MPGeneratedSiteEntity class]]) {
[context saveToStore]; ((MPGeneratedSiteEntity *)entity).counter = counter;
[context saveToStore];
[self updateContent:entity]; [self updateContent:entity];
} }
}]; }];
else
[self updateContent];
} }
- (BOOL)generated { - (BOOL)generated {
@ -117,36 +153,60 @@
return self.type & MPSiteTypeClassStored; return self.type & MPSiteTypeClassStored;
} }
- (BOOL)transient {
return _entityOID == nil;
}
- (void)updateContent { - (void)updateContent {
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { if (_entityOID)
[self updateContent:[MPSiteEntity existingObjectWithID:_entityOID inContext:context]]; [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
}]; [self updateContent:[MPSiteEntity existingObjectWithID:_entityOID inContext:context]];
}];
else
PearlNotMainQueue( ^{
NSString *password = [self.algorithm generatePasswordForSiteNamed:self.name ofType:self.type withCounter:self.counter
usingKey:[MPAppDelegate_Shared get].key];
NSString *loginName = [self.algorithm generateLoginForSiteNamed:self.name usingKey:[MPAppDelegate_Shared get].key];
[self updatePasswordWithResult:password];
[self updateLoginNameWithResult:loginName];
} );
} }
- (void)updateContent:(MPSiteEntity *)entity { - (void)updateContent:(MPSiteEntity *)entity {
[entity resolvePasswordUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
[self updatePasswordWithResult:result];
}];
[entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
[self updateLoginNameWithResult:result];
}];
}
- (void)updatePasswordWithResult:(NSString *)result {
static NSRegularExpression *re_anyChar; static NSRegularExpression *re_anyChar;
static dispatch_once_t once = 0; static dispatch_once_t once = 0;
dispatch_once( &once, ^{ dispatch_once( &once, ^{
re_anyChar = [NSRegularExpression regularExpressionWithPattern:@"." options:0 error:nil]; re_anyChar = [NSRegularExpression regularExpressionWithPattern:@"." options:0 error:nil];
} ); } );
[entity resolvePasswordUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) { NSString *displayResult = result;
NSString *displayResult = result; if ([[MPConfig get].hidePasswords boolValue] && !([NSEvent modifierFlags] & NSAlternateKeyMask))
if ([[MPConfig get].hidePasswords boolValue] && !([NSEvent modifierFlags] & NSAlternateKeyMask)) displayResult = [displayResult stringByReplacingMatchesOfExpression:re_anyChar withTemplate:@"●"];
displayResult = [displayResult stringByReplacingMatchesOfExpression:re_anyChar withTemplate:@"●"];
PearlMainQueue( ^{ PearlMainQueue( ^{
self.content = result; self.content = result;
self.displayedContent = displayResult; self.displayedContent = displayResult;
} ); } );
}]; }
[entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
PearlMainQueue( ^{ - (void)updateLoginNameWithResult:(NSString *)loginName {
self.loginName = result;
} ); PearlMainQueue( ^{
}]; self.loginName = loginName;
} );
} }
@end @end