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 +5 -0
- data/INSTALL +6 -0
- data/LICENSE +25 -0
- data/README +7 -0
- data/Rakefile +61 -0
- data/TODO +3 -0
- data/VERSION +1 -0
- data/example/example.rb +8 -0
- data/ext/extconf.rb +6 -0
- data/ext/rkeychain.c +179 -0
- metadata +65 -0
data/CHANGELOG
ADDED
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
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
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/example/example.rb
ADDED
@@ -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
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
|
+
|