Skip to content
This repository has been archived by the owner on Aug 24, 2019. It is now read-only.

Commit

Permalink
Clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
soffes committed Mar 21, 2013
1 parent 801dd82 commit 99579d5
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 43 deletions.
27 changes: 23 additions & 4 deletions Rakefile
@@ -1,7 +1,26 @@
class String
def self.colorize(text, color_code)
"\e[#{color_code}m#{text}\e[0m"
end

def red
self.class.colorize(self, 31)
end

def green
self.class.colorize(self, 32)
end
end

desc 'Run the tests'
task :test do
test_scheme 'SSKeychainTests-Mac'
test_scheme 'SSKeychainTests-iOS'
verbose = ENV['VERBOSE']
mac = test_scheme('SSKeychainTests-Mac', verbose)
ios = test_scheme('SSKeychainTests-iOS', verbose)

puts "\n\n\n" if verbose
puts "Mac: #{mac == 0 ? 'PASSED'.green : 'FAILED'.red}"
puts "iOS: #{ios == 0 ? 'PASSED'.green : 'FAILED'.red}"
end

task :default => :test
Expand Down Expand Up @@ -44,11 +63,11 @@ namespace :docs do
end
end

def test_scheme(scheme)
def test_scheme(scheme, verbose = false)
command = "xcodebuild -project Tests/SSKeychain.xcodeproj -scheme #{scheme} TEST_AFTER_BUILD=YES 2>&1"
IO.popen(command) do |io|
while line = io.gets do
puts line
puts line if verbose
if line == "** BUILD SUCCEEDED **\n"
return 0
elsif line == "** BUILD FAILED **\n"
Expand Down
31 changes: 21 additions & 10 deletions Readme.markdown
Expand Up @@ -2,9 +2,7 @@

SSKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keychain on Mac OS X and iOS.

This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it).

## Adding to your project
## Adding to Your Project

1. Add `Security.framework` to your target
2. Add `SSKeychain.h`, `SSKeychain.m`, `SSKeychainQuery.h`, and `SSKeychainQuery.m` to your project.
Expand All @@ -13,7 +11,7 @@ SSKeychain requires ARC.

Note: Currently SSKeychain does not support Mac OS 10.6.

## Working with the keychain
## Working with the Keychain

SSKeychain has the following class methods for working with the system keychain:

Expand Down Expand Up @@ -46,18 +44,31 @@ You can also **read the [SSKeychain Documentation](http://docs.samsoff.es/SSKeyc

## Debugging

If your saving to the keychain fails, use the NSError object to handle it. You can invoke `[error code]` to get the numeric error
code. A few values are defined in SSKeychain.h, and the rest in SecBase.h.
If your saving to the keychain fails, use the NSError object to handle it. You can invoke `[error code]` to get the numeric error code. A few values are defined in SSKeychain.h, and the rest in SecBase.h.

```objective-c
NSError *error = nil;
NSString *password = [SSKeychain passwordForService:@"MyService" account:@"samsoffes" error:&error];
SSKeychainQuery *query = [[SSKeychainQuery alloc] init];
query.service = @"MyService";
query.account = @"soffes";
[query fetch:&error];

if ([error code] == SSKeychainErrorNotFound) {
if ([error code] == errSecItemNotFound) {
NSLog(@"Password not found");
} else if (error != nil) {
NSLog(@"Some other error occurred: %@", error);
NSLog(@"Some other error occurred: %@", [error localizedDescription]);
}
```
Obviously, you should do something more sophisticated. Working with the keychain is pretty sucky. You should really check for errors and failures. This library doesn't make it any more stable, it just wraps up all of the annoying C APIs.
Obviously, you should do something more sophisticated. You can just call `[error localizedDescription]` if all you need is the error message.
## Disclaimer
Working with the keychain is pretty sucky. You should really check for errors and failures. This library doesn't make it any more stable, it just wraps up all of the annoying C APIs.
## Thanks
This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it).
A huge thanks to [Caleb Davenport](https://github.com/calebd) for leading the way on version 1.0 of SSKeychain.
23 changes: 8 additions & 15 deletions SSKeychain/SSKeychain.h
@@ -1,9 +1,9 @@
//
// SSKeychain.h
// SSToolkit
// SSKeychain
//
// Created by Sam Soffes on 5/19/10.
// Copyright (c) 2009-2011 Sam Soffes. All rights reserved.
// Copyright (c) 2010-2013 Sam Soffes. All rights reserved.
//

#import "SSKeychainQuery.h"
Expand Down Expand Up @@ -72,11 +72,10 @@ extern NSString *const kSSKeychainWhereKey;
@return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't
have a password for the given parameters.
@see passwordForService:account:error:
*/
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;


/**
Deletes a password from the Keychain.
Expand All @@ -85,11 +84,10 @@ extern NSString *const kSSKeychainWhereKey;
@param account The account for which to delete the corresponding password.
@return Returns `YES` on success, or `NO` on failure.
@see deletePasswordForService:account:error:
*/
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;


/**
Sets a password in the Keychain.
Expand All @@ -100,11 +98,10 @@ extern NSString *const kSSKeychainWhereKey;
@param account The account for which to set the corresponding password.
@return Returns `YES` on success, or `NO` on failure.
@see setPassword:forService:account:error:
*/
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;


/**
Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts.
Expand All @@ -113,11 +110,10 @@ extern NSString *const kSSKeychainWhereKey;
@return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
accounts. The order of the objects in the array isn't defined.
@see allAccounts:
*/
+ (NSArray *)allAccounts;


/**
Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any
accounts for the given service.
Expand All @@ -129,11 +125,10 @@ extern NSString *const kSSKeychainWhereKey;
@return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain
doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined.
@see accountsForService:error:
*/
+ (NSArray *)accountsForService:(NSString *)serviceName;


#pragma mark - Configuration

#if __IPHONE_4_0 && TARGET_OS_IPHONE
Expand All @@ -145,7 +140,7 @@ extern NSString *const kSSKeychainWhereKey;
The return value will be `NULL` or one of the "Keychain Item Accessibility
Constants" used for determining when a keychain item should be readable.
@see accessibilityType
@see setAccessibilityType
*/
+ (CFTypeRef)accessibilityType;

Expand All @@ -163,5 +158,3 @@ extern NSString *const kSSKeychainWhereKey;
#endif

@end


4 changes: 2 additions & 2 deletions SSKeychain/SSKeychain.m
@@ -1,9 +1,9 @@
//
// SSKeychain.m
// SSToolkit
// SSKeychain
//
// Created by Sam Soffes on 5/19/10.
// Copyright (c) 2009-2011 Sam Soffes. All rights reserved.
// Copyright (c) 2010-2013 Sam Soffes. All rights reserved.
//

#import "SSKeychain.h"
Expand Down
1 change: 1 addition & 0 deletions SSKeychain/SSKeychainQuery.h
Expand Up @@ -7,6 +7,7 @@
//

#import <Foundation/Foundation.h>
#import <Security/Security.h>

/**
Simple interface for querying or modifying keychain items.
Expand Down
51 changes: 39 additions & 12 deletions SSKeychain/SSKeychainQuery.m
Expand Up @@ -6,8 +6,6 @@
// Copyright (c) 2013 Sam Soffes. All rights reserved.
//

#import <Security/Security.h>

#import "SSKeychainQuery.h"
#import "SSKeychain.h"

Expand Down Expand Up @@ -175,16 +173,45 @@ + (NSError *)errorWithCode:(OSStatus) code {
case SSKeychainErrorBadArguments: message = @"Some of the arguments were invalid"; break;

#if TARGET_OS_IPHONE
case errSecUnimplemented: message = @"Function or operation not implemented"; break;
case errSecParam: message = @"One or more parameters passed to a function were not valid"; break;
case errSecAllocate: message = @"Failed to allocate memory"; break;
case errSecNotAvailable: message = @"No keychain is available. You may need to restart your computer"; break;
case errSecDuplicateItem: message = @"The specified item already exists in the keychain"; break;
case errSecItemNotFound: message = @"The specified item could not be found in the keychain"; break;
case errSecInteractionNotAllowed: message = @"User interaction is not allowed"; break;
case errSecDecode: message = @"Unable to decode the provided data"; break;
case errSecAuthFailed: message = @"The user name or passphrase you entered is not correct"; break;
default: message = @"Refer to SecBase.h for description";
case errSecUnimplemented: {
message = @"Function or operation not implemented";
break;
}
case errSecParam: {
message = @"One or more parameters passed to a function were not valid";
break;
}
case errSecAllocate: {
message = @"Failed to allocate memory";
break;
}
case errSecNotAvailable: {
message = @"No keychain is available. You may need to restart your computer";
break;
}
case errSecDuplicateItem: {
message = @"The specified item already exists in the keychain";
break;
}
case errSecItemNotFound: {
message = @"The specified item could not be found in the keychain";
break;
}
case errSecInteractionNotAllowed: {
message = @"User interaction is not allowed";
break;
}
case errSecDecode: {
message = @"Unable to decode the provided data";
break;
}
case errSecAuthFailed: {
message = @"The user name or passphrase you entered is not correct";
break;
}
default: {
message = @"Refer to SecBase.h for description";
}
#else
default:
message = (__bridge_transfer NSString *)SecCopyErrorMessageString(code, NULL);
Expand Down

0 comments on commit 99579d5

Please sign in to comment.