ruby-openid-apps-discovery 1.0.2 → 1.01
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/lib/gapps_openid.rb +36 -71
- metadata +2 -2
data/lib/gapps_openid.rb
CHANGED
@@ -29,17 +29,10 @@ require 'base64'
|
|
29
29
|
# Caching of discovery information is enabled when used with rails. In other environments,
|
30
30
|
# a cache can be set via:
|
31
31
|
#
|
32
|
-
# OpenID.cache = ...
|
32
|
+
# OpenID::GoogleDiscovery.cache = ...
|
33
33
|
#
|
34
34
|
# The cache must implement methods read(key) and write(key,value)
|
35
35
|
#
|
36
|
-
# Similarly, logging will attempt to use the default Rail's logger, but can be overriden
|
37
|
-
# by calling
|
38
|
-
#
|
39
|
-
# OpenID.logger = ...
|
40
|
-
#
|
41
|
-
# The logger must respond to warn, debug, and info methods
|
42
|
-
#
|
43
36
|
# In some cases additional setup is required, particularly to set the location of trusted
|
44
37
|
# root certificates for validating XRDS signatures. If standard locations don't work, additional
|
45
38
|
# files and directories can be added via:
|
@@ -88,13 +81,11 @@ module OpenID
|
|
88
81
|
def perform_discovery(uri)
|
89
82
|
OpenID.logger.debug("Performing discovery for #{uri}") unless OpenID.logger.nil?
|
90
83
|
begin
|
91
|
-
domain = uri
|
92
84
|
parsed_uri = URI::parse(uri)
|
93
|
-
|
94
|
-
|
95
|
-
return discover_site(domain)
|
85
|
+
if parsed_uri.scheme.nil?
|
86
|
+
return discover_site(uri)
|
96
87
|
end
|
97
|
-
return discover_user(
|
88
|
+
return discover_user(parsed_uri.host, uri)
|
98
89
|
rescue Exception => e
|
99
90
|
# If we fail, just return nothing and fallback on default discovery mechanisms
|
100
91
|
OpenID.logger.warn("Unexpected exception performing discovery for id #{uri}: #{e}") unless OpenID.logger.nil?
|
@@ -102,10 +93,6 @@ module OpenID
|
|
102
93
|
end
|
103
94
|
end
|
104
95
|
|
105
|
-
def site_identifier?(parsed_uri)
|
106
|
-
return parsed_uri.scheme.nil? || parsed_uri.path.nil? || parsed_uri.path.strip.empty?
|
107
|
-
end
|
108
|
-
|
109
96
|
# Handles discovery for a user's claimed ID.
|
110
97
|
def discover_user(domain, claimed_id)
|
111
98
|
OpenID.logger.debug("Discovering user identity #{claimed_id} for domain #{domain}") unless OpenID.logger.nil?
|
@@ -114,23 +101,13 @@ module OpenID
|
|
114
101
|
OpenID.logger.debug("#{domain} is not a Google Apps domain, aborting") unless OpenID.logger.nil?
|
115
102
|
return nil # Not a Google Apps domain
|
116
103
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
# TODO - Need to propogate secure discovery info up through stack
|
122
|
-
user_url, authority = get_user_xrds_url(xrds, claimed_id)
|
123
|
-
user_xrds, signed = fetch_secure_xrds(domain, user_url, false)
|
124
|
-
|
125
|
-
# No user xrds -- likely that identifier was just OP identifier
|
126
|
-
if user_xrds.nil?
|
127
|
-
endpoints = OpenID::OpenIDServiceEndpoint.from_xrds(domain, xrds)
|
128
|
-
return [claimed_id, OpenID.get_op_or_user_services(endpoints)]
|
129
|
-
end
|
104
|
+
xrds = fetch_xrds(domain, url)
|
105
|
+
user_url, authority = get_user_xrds_url(xrds, claimed_id)
|
106
|
+
user_xrds = fetch_xrds(authority, user_url, false)
|
107
|
+
return if user_xrds.nil?
|
130
108
|
|
131
|
-
|
132
|
-
|
133
|
-
end
|
109
|
+
endpoints = OpenID::OpenIDServiceEndpoint.from_xrds(claimed_id, user_xrds)
|
110
|
+
return [claimed_id, OpenID.get_op_or_user_services(endpoints)]
|
134
111
|
end
|
135
112
|
|
136
113
|
# Handles discovery for a domain
|
@@ -141,12 +118,10 @@ module OpenID
|
|
141
118
|
OpenID.logger.debug("#{domain} is not a Google Apps domain, aborting") unless OpenID.logger.nil?
|
142
119
|
return nil # Not a Google Apps domain
|
143
120
|
end
|
144
|
-
xrds
|
145
|
-
|
121
|
+
xrds = fetch_xrds(domain, url)
|
146
122
|
unless xrds.nil?
|
147
|
-
|
148
|
-
|
149
|
-
return [domain, OpenID.get_op_or_user_services(endpoints)]
|
123
|
+
endpoints = OpenID::OpenIDServiceEndpoint.from_xrds(domain, xrds)
|
124
|
+
return [domain, OpenID.get_op_or_user_services(endpoints)]
|
150
125
|
end
|
151
126
|
return nil
|
152
127
|
end
|
@@ -158,9 +133,11 @@ module OpenID
|
|
158
133
|
return cached_value unless cached_value.nil?
|
159
134
|
|
160
135
|
host_meta_url = "https://www.google.com/accounts/o8/.well-known/host-meta?hd=#{CGI::escape(domain)}"
|
161
|
-
http_resp =
|
162
|
-
|
163
|
-
|
136
|
+
http_resp = OpenID.fetch(host_meta_url)
|
137
|
+
if http_resp.code != "200" and http_resp.code != "206"
|
138
|
+
OpenID.logger.debug("Received #{http_resp.code} when fetching #{host_meta_url}") unless OpenID.logger.nil?
|
139
|
+
return nil
|
140
|
+
end
|
164
141
|
matches = /Link: <(.*)>/.match( http_resp.body )
|
165
142
|
if matches.nil?
|
166
143
|
OpenID.logger.debug("No link tag found at #{host_meta_url}") unless OpenID.logger.nil?
|
@@ -170,43 +147,34 @@ module OpenID
|
|
170
147
|
return matches[1]
|
171
148
|
end
|
172
149
|
|
173
|
-
def fetch_url(url)
|
174
|
-
http_resp = OpenID.fetch(url)
|
175
|
-
if http_resp.code != "200" and http_resp.code != "206"
|
176
|
-
OpenID.logger.debug("Received #{http_resp.code} when fetching #{url}") unless OpenID.logger.nil?
|
177
|
-
return nil
|
178
|
-
end
|
179
|
-
return http_resp
|
180
|
-
end
|
181
|
-
|
182
150
|
# Fetches the XRDS and verifies the signature and authority for the doc
|
183
|
-
def
|
151
|
+
def fetch_xrds(authority, url, cache=true)
|
184
152
|
return if url.nil?
|
185
153
|
|
186
154
|
OpenID.logger.debug("Retrieving XRDS from #{url}") unless OpenID.logger.nil?
|
187
155
|
|
188
|
-
cached_xrds = get_cache(
|
156
|
+
cached_xrds = get_cache(url)
|
189
157
|
return cached_xrds unless cached_xrds.nil?
|
190
158
|
|
191
|
-
http_resp =
|
192
|
-
|
159
|
+
http_resp = OpenID.fetch(url)
|
160
|
+
if http_resp.code != "200" and http_resp.code != "206"
|
161
|
+
OpenID.logger.debug("Received #{http_resp.code} when fetching #{url}") unless OpenID.logger.nil?
|
162
|
+
return nil
|
163
|
+
end
|
193
164
|
|
194
165
|
body = http_resp.body
|
195
|
-
put_cache("XRDS_#{url}", body)
|
196
|
-
|
197
166
|
signature = http_resp["Signature"]
|
198
167
|
signed_by = SimpleSign.verify(body, signature)
|
199
|
-
|
200
|
-
if signed_by.nil?
|
201
|
-
put_cache("XRDS_#{url}", body) if cache
|
202
|
-
return [body, false]
|
203
|
-
elsif signed_by.casecmp(authority) || signed_by.casecmp('hosted-id.google.com')
|
204
|
-
put_cache("XRDS_#{url}", body) if cache
|
205
|
-
return [body, true]
|
206
|
-
else
|
168
|
+
if !signed_by.casecmp(authority) or !signed_by.casecmp('hosted-id.google.com')
|
207
169
|
OpenID.logger.warn("Expected signature from #{authority} but found #{signed_by}") unless OpenID.logger.nil?
|
208
|
-
return
|
170
|
+
return false # Signed, but not by the right domain.
|
209
171
|
end
|
172
|
+
|
173
|
+
# Everything is OK
|
174
|
+
if cache
|
175
|
+
put_cache(url, body)
|
176
|
+
end
|
177
|
+
return body
|
210
178
|
end
|
211
179
|
|
212
180
|
# Process the URITemplate in the XRDS to derive the location of the claimed id's XRDS
|
@@ -289,15 +257,12 @@ module OpenID
|
|
289
257
|
|
290
258
|
# Verifies the signature of the doc, returning the CN of the signer if valid
|
291
259
|
def self.verify(xml, signature_value)
|
292
|
-
|
293
|
-
|
294
|
-
return nil if REXML::XPath.first(doc, "//ds:Signature").nil? and signature_value.nil?
|
295
|
-
|
260
|
+
raise "Missing signature value" if signature_value.nil?
|
296
261
|
decoded_sig = Base64.decode64(signature_value)
|
262
|
+
|
263
|
+
doc = REXML::Document.new(xml)
|
297
264
|
certs = self.parse_certificates(doc)
|
298
265
|
raise "No signature in document" if certs.nil? or certs.empty?
|
299
|
-
raise "Missing signature value" if signature_value.nil?
|
300
|
-
|
301
266
|
|
302
267
|
signing_certificate = certs.first
|
303
268
|
raise "Invalid signature" if !signing_certificate.public_key.verify(OpenSSL::Digest::SHA1.new, decoded_sig, xml)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-openid-apps-discovery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: "1.01"
|
5
5
|
platform: ruby
|
6
6
|
authors: []
|
7
7
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-01-12 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|