rkeychain 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG ADDED
@@ -0,0 +1,5 @@
1
+ = CHANGELOG
2
+
3
+ == Version 0.1.0
4
+
5
+ Initial release.
data/INSTALL ADDED
@@ -0,0 +1,6 @@
1
+ = Installation
2
+
3
+ # gem install rkeychain
4
+
5
+
6
+
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ = License
2
+
3
+ Copyright (c) 2007, Oliver Lohmann
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+ * Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+ * The names of its contributors may be used to endorse or promote products
14
+ derived from this software without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY OLIVER LOHMANN ``AS IS'' AND ANY
17
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL OLIVER LOHMANN BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,7 @@
1
+ = rkeychain
2
+
3
+ rkeychain provides access to MacOS X' keychain facilities which are part of the
4
+ security framework.
5
+
6
+ == Author
7
+ Oliver Lohmann (olohmann@gmail.com)
data/Rakefile ADDED
@@ -0,0 +1,61 @@
1
+ require "rake/rdoctask"
2
+ require "rake/testtask"
3
+ require "rake/gempackagetask"
4
+
5
+ require "rubygems"
6
+
7
+ dir = File.dirname(__FILE__)
8
+ ext = File.join(dir, "ext", "rkeychain.bundle")
9
+ doc_extra_files = ["README", "INSTALL", "TODO",
10
+ "CHANGELOG", "LICENSE", "ext/rkeychain.c"]
11
+ version = File.read("VERSION").chomp
12
+
13
+ task :default => [:clean, :rdoc, :package]
14
+
15
+ desc "Clean up project directory"
16
+ task :clean do
17
+ rm_rf "doc"
18
+ rm_rf "pkg"
19
+ end
20
+
21
+ Rake::RDocTask.new do |rdoc|
22
+ rdoc.rdoc_files = doc_extra_files
23
+ rdoc.main = "README"
24
+ rdoc.rdoc_dir = "doc/html"
25
+ rdoc.title = "Keychain Documentation"
26
+ end
27
+
28
+ spec = Gem::Specification.new do |spec|
29
+ spec.name = "rkeychain"
30
+ spec.version = version
31
+ spec.platform = Gem::Platform::RUBY
32
+ spec.summary = "rkeychain provides access to MacOS X' keychain facilities."
33
+ spec.files = Rake::FileList.new(["**/*"]) do |fl|
34
+ fl.exclude(".svn")
35
+ fl.exclude("doc")
36
+ fl.exclude("pkg")
37
+ fl.exclude("*.log")
38
+ end
39
+
40
+ spec.has_rdoc = true
41
+ spec.extra_rdoc_files = doc_extra_files
42
+ spec.rdoc_options << '--title' << 'Keychain Documentation' <<
43
+ '--main' << 'README'
44
+
45
+ spec.require_path << "ext"
46
+ spec.extensions = "ext/extconf.rb"
47
+
48
+ spec.author = "Oliver Lohmann"
49
+ spec.email = "olohmann@gmail.com"
50
+ spec.rubyforge_project = "rkeychain"
51
+ spec.homepage = "http://rkeychain.rubyforge.org"
52
+ spec.description = <<END_DESC
53
+ rkeychain provides access to MacOS X' keychain facilities which are part of the
54
+ security framework.
55
+ END_DESC
56
+ end
57
+
58
+ Rake::GemPackageTask.new(spec) do |pkg|
59
+ pkg.need_zip = true
60
+ pkg.need_tar = true
61
+ end
data/TODO ADDED
@@ -0,0 +1,3 @@
1
+ = TODO
2
+
3
+ * Support the full functionality of the Security Framework regarding keychain access. (Overview: http://developer.apple.com/documentation/Security/Reference/keychainservices/index.html#//apple_ref/doc/uid/TP30000898)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,8 @@
1
+ require "rubygems"
2
+ require "rkeychain"
3
+
4
+ # lookup the password of the user's gmail account (if it is stored in
5
+ # the standard "login" keychain.
6
+ # Use it for accessing gcalendar, gmail or whatever...
7
+ passwd = Keychain.lookup_internet_passwd({"serverName" =>"mail.google.com"})
8
+ puts "Your passwd@mail.google.com is: #{passwd}"
data/ext/extconf.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS += " -isysroot /Developer/SDKs/MacOSX10.4u.sdk"
4
+ $LDFLAGS += " -framework CoreFoundation -framework Security -framework CoreServices -isysroot /Developer/SDKs/MacOSX10.4u.sdk "
5
+
6
+ create_makefile("rkeychain")
data/ext/rkeychain.c ADDED
@@ -0,0 +1,179 @@
1
+ #include <CoreFoundation/CoreFoundation.h>
2
+ #include <Security/Security.h>
3
+ #include <CoreServices/CoreServices.h>
4
+
5
+ #include <ruby.h>
6
+
7
+ static VALUE __s_generic_passwd(VALUE self,
8
+ VALUE keychain,
9
+ VALUE serviceName,
10
+ VALUE accontName)
11
+ {
12
+ VALUE str;
13
+
14
+ OSStatus status;
15
+ UInt32 passwordLength;
16
+ void *passwordData;
17
+ SecKeychainItemRef itemRef = nil;
18
+ SecKeychainRef s_keychain = NULL;
19
+
20
+ if (keychain != Qnil) {
21
+ if (TYPE(keychain) != T_STRING) {
22
+ rb_raise(rb_eTypeError, "string value required");
23
+ }
24
+
25
+ status = SecKeychainOpen(RSTRING(keychain)->ptr, &s_keychain);
26
+ if (status != noErr) {
27
+ return Qnil;
28
+ }
29
+ }
30
+
31
+ status = SecKeychainFindGenericPassword(s_keychain,
32
+ RSTRING(serviceName)->len, RSTRING(serviceName)->ptr,
33
+ RSTRING(accontName)->len, RSTRING(accontName)->ptr,
34
+ &passwordLength, &passwordData, NULL);
35
+
36
+ if (status == noErr) {
37
+ str = rb_str_new2(passwordData);
38
+ SecKeychainItemFreeContent(NULL, passwordData);
39
+ }
40
+ else {
41
+ str = Qnil;
42
+ }
43
+
44
+ if (s_keychain != NULL) {
45
+ CFRelease(s_keychain);
46
+ }
47
+
48
+ return str;
49
+ }
50
+
51
+ /*
52
+ * On success the lookup returns the *first* password string which
53
+ * matches the specified query else it returns nil.
54
+ * Unless you granted the application permanent access to a keychain,
55
+ * a dialog window will appear, asking for permission to read
56
+ * the password information from it.
57
+ *
58
+ * A hash with following key/values is accepted (a serviceName OR an accountName is mandatory):
59
+ * "keychain" => <path to keychain> (default: login.keychain)
60
+ * "serviceName" => <service name string> (default: "")
61
+ * "accountName" => <account name string> (default: "")
62
+ */
63
+ static VALUE s_lookup_generic_passwd(VALUE self, VALUE hash)
64
+ {
65
+ VALUE keychain = rb_hash_aref(hash, rb_str_new2("keychain"));
66
+ VALUE serviceName = rb_hash_aref(hash, rb_str_new2("serviceName"));
67
+ VALUE accountName = rb_hash_aref(hash, rb_str_new2("accountName"));
68
+
69
+ serviceName = serviceName == Qnil ? rb_str_new2("") : serviceName;
70
+ accountName = accountName == Qnil ? rb_str_new2("") : accountName;
71
+
72
+ if (TYPE(accountName) != T_STRING) {
73
+ rb_raise(rb_eTypeError, "string value required");
74
+ }
75
+
76
+ if (TYPE(serviceName) != T_STRING) {
77
+ rb_raise(rb_eTypeError, "string value required");
78
+ }
79
+
80
+
81
+ return __s_generic_passwd(self, keychain, serviceName, accountName);
82
+ }
83
+
84
+
85
+ static VALUE __s_internet_passwd(VALUE self, VALUE keychain, VALUE serverName, VALUE accountName)
86
+
87
+ {
88
+ VALUE str;
89
+
90
+ OSStatus status;
91
+ UInt32 passwordLength;
92
+ void *passwordData;
93
+ SecKeychainItemRef itemRef = nil;
94
+ SecKeychainRef s_keychain = NULL;
95
+
96
+ if (keychain != Qnil) {
97
+ if (TYPE(keychain) != T_STRING) {
98
+ rb_raise(rb_eTypeError, "string value required");
99
+ }
100
+
101
+ status = SecKeychainOpen(RSTRING(keychain)->ptr, &s_keychain);
102
+ if (status != noErr) {
103
+ return Qnil;
104
+ }
105
+ }
106
+
107
+ status = SecKeychainFindInternetPassword(s_keychain,
108
+ RSTRING(serverName)->len, RSTRING(serverName)->ptr,
109
+ 0, NULL, /* security domain */
110
+ RSTRING(accountName)->len, RSTRING(accountName)->ptr,
111
+ 0, NULL, /* path */
112
+ 0, /* port */
113
+ 0, /* protocol */
114
+ kSecAuthenticationTypeDefault, /* auth type */
115
+ &passwordLength, &passwordData, NULL);
116
+
117
+
118
+ if (status == noErr) {
119
+ str = rb_str_new2(passwordData);
120
+ SecKeychainItemFreeContent(NULL, passwordData);
121
+ }
122
+ else {
123
+ str = Qnil;
124
+ }
125
+
126
+ if (s_keychain != NULL) {
127
+ CFRelease(s_keychain);
128
+ }
129
+
130
+ return str;
131
+
132
+
133
+ }
134
+
135
+ /*
136
+ * On success the lookup returns the *first* password string which
137
+ * matches the specified query else it returns nil.
138
+ * Unless you granted the application permanent access to a keychain,
139
+ * a dialog window will appear, asking for permission to read
140
+ * the password information from it.
141
+ *
142
+ * A hash with following key/values is accepted (a serverName OR an accountName is mandatory):
143
+ * "keychain" => <path to keychain> (default: login.keychain)
144
+ * "serverName" => <service name string> (default: "")
145
+ * "accountName" => <account name string> (default: "")
146
+ */
147
+ static VALUE s_lookup_internet_passwd(VALUE self, VALUE hash)
148
+ {
149
+ VALUE str;
150
+
151
+ VALUE keychain = rb_hash_aref(hash, rb_str_new2("keychain"));
152
+ VALUE serverName = rb_hash_aref(hash, rb_str_new2("serverName"));
153
+ VALUE accountName = rb_hash_aref(hash, rb_str_new2("accountName"));
154
+
155
+ serverName = serverName == Qnil ? rb_str_new2("") : serverName;
156
+ accountName = accountName == Qnil ? rb_str_new2("") : accountName;
157
+
158
+ if (TYPE(accountName) != T_STRING) {
159
+ rb_raise(rb_eTypeError, "string value required");
160
+ }
161
+
162
+ if (TYPE(serverName) != T_STRING) {
163
+ rb_raise(rb_eTypeError, "string value required");
164
+ }
165
+
166
+ return __s_internet_passwd(self, keychain, serverName, accountName);
167
+ }
168
+
169
+ /*
170
+ * Module: Keychain
171
+ */
172
+ VALUE cKeychain;
173
+ void Init_rkeychain()
174
+ {
175
+ cKeychain = rb_define_module("Keychain");
176
+ rb_define_module_function(cKeychain, "lookup_generic_passwd", s_lookup_generic_passwd, 1);
177
+ rb_define_module_function(cKeychain, "lookup_internet_passwd", s_lookup_internet_passwd, 1);
178
+ }
179
+
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.1
3
+ specification_version: 1
4
+ name: rkeychain
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2007-03-02 00:00:00 +13:00
8
+ summary: rkeychain provides access to MacOS X' keychain facilities.
9
+ require_paths:
10
+ - libext
11
+ email: olohmann@gmail.com
12
+ homepage: http://rkeychain.rubyforge.org
13
+ rubyforge_project: rkeychain
14
+ description: rkeychain provides access to MacOS X' keychain facilities which are part of the security framework.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Oliver Lohmann
31
+ files:
32
+ - CHANGELOG
33
+ - example
34
+ - ext
35
+ - INSTALL
36
+ - LICENSE
37
+ - Rakefile
38
+ - README
39
+ - TODO
40
+ - VERSION
41
+ - example/example.rb
42
+ - ext/extconf.rb
43
+ - ext/rkeychain.c
44
+ test_files: []
45
+
46
+ rdoc_options:
47
+ - --title
48
+ - Keychain Documentation
49
+ - --main
50
+ - README
51
+ extra_rdoc_files:
52
+ - README
53
+ - INSTALL
54
+ - TODO
55
+ - CHANGELOG
56
+ - LICENSE
57
+ - ext/rkeychain.c
58
+ executables: []
59
+
60
+ extensions:
61
+ - ext/extconf.rb
62
+ requirements: []
63
+
64
+ dependencies: []
65
+