has_global_session 0.9.3 → 0.9.5

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.
@@ -7,8 +7,8 @@ spec = Gem::Specification.new do |s|
7
7
  s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
8
8
 
9
9
  s.name = 'has_global_session'
10
- s.version = '0.9.3'
11
- s.date = '2010-07-19'
10
+ s.version = '0.9.5'
11
+ s.date = '2010-07-20'
12
12
 
13
13
  s.authors = ['Tony Spataro']
14
14
  s.email = 'code@tracker.xeger.net'
@@ -23,6 +23,7 @@ spec = Gem::Specification.new do |s|
23
23
 
24
24
  s.add_development_dependency('rspec', [">= 1.3.0"])
25
25
  s.add_development_dependency('flexmock', [">= 0.8.6"])
26
+ s.add_development_dependency('actionpack', [">= 2.1.2"])
26
27
 
27
28
  basedir = File.dirname(__FILE__)
28
29
  candidates = ['has_global_session.gemspec', 'init.rb', 'MIT-LICENSE', 'README.rdoc'] +
@@ -9,13 +9,13 @@ module HasGlobalSession
9
9
  class GlobalSession
10
10
  attr_reader :id, :authority, :created_at, :expired_at, :directory
11
11
 
12
- def initialize(directory, cookie=nil)
12
+ def initialize(directory, cookie=nil, valid_signature_digest=nil)
13
13
  @schema_signed = Set.new((Configuration['attributes']['signed']))
14
14
  @schema_insecure = Set.new((Configuration['attributes']['insecure']))
15
15
  @directory = directory
16
16
 
17
17
  if cookie
18
- load_from_cookie(cookie)
18
+ load_from_cookie(cookie, valid_signature_digest)
19
19
  elsif @directory.local_authority_name
20
20
  create_from_scratch
21
21
  else
@@ -40,17 +40,16 @@ module HasGlobalSession
40
40
  if @signature && !@dirty_secure
41
41
  #use cached signature unless we've changed secure state
42
42
  authority = @authority
43
- signature = @signature
44
43
  else
45
44
  authority_check
46
45
  authority = @directory.local_authority_name
47
46
  hash['a'] = authority
48
- digest = digest(hash)
49
- signature = Encoding::Base64Cookie.dump(@directory.private_key.private_encrypt(digest))
47
+ digest = canonical_digest(hash)
48
+ @signature = Encoding::Base64Cookie.dump(@directory.private_key.private_encrypt(digest))
50
49
  end
51
50
 
52
51
  hash['dx'] = @insecure
53
- hash['s'] = signature
52
+ hash['s'] = @signature
54
53
  hash['a'] = authority
55
54
 
56
55
  json = Encoding::JSON.dump(hash)
@@ -66,6 +65,10 @@ module HasGlobalSession
66
65
  @signed.has_key(key) || @insecure.has_key?(key)
67
66
  end
68
67
 
68
+ def signature_digest
69
+ @signature ? digest(@signature) : nil
70
+ end
71
+
69
72
  def keys
70
73
  @signed.keys + @insecure.keys
71
74
  end
@@ -119,9 +122,13 @@ module HasGlobalSession
119
122
  end
120
123
  end
121
124
 
122
- def digest(input)
125
+ def canonical_digest(input)
123
126
  canonical = Encoding::JSON.dump(canonicalize(input))
124
- return Digest::SHA1.new().update(canonical).hexdigest
127
+ return digest(canonical)
128
+ end
129
+
130
+ def digest(input)
131
+ return Digest::SHA1.new().update(input).hexdigest
125
132
  end
126
133
 
127
134
  def canonicalize(input)
@@ -143,7 +150,7 @@ module HasGlobalSession
143
150
  return output
144
151
  end
145
152
 
146
- def load_from_cookie(cookie)
153
+ def load_from_cookie(cookie, valid_signature_digest)
147
154
  zbin = Encoding::Base64Cookie.load(cookie)
148
155
  json = Zlib::Inflate.inflate(zbin)
149
156
  hash = Encoding::JSON.load(json)
@@ -156,15 +163,17 @@ module HasGlobalSession
156
163
  insecure = hash.delete('dx')
157
164
  signature = hash.delete('s')
158
165
 
159
- #Check signature
160
- expected = digest(hash)
161
- signer = @directory.authorities[authority]
162
- raise SecurityError, "Unknown signing authority #{authority}" unless signer
163
- got = signer.public_decrypt(Encoding::Base64Cookie.load(signature))
164
- unless (got == expected)
165
- raise SecurityError, "Signature mismatch on global session cookie; tampering suspected"
166
+ unless valid_signature_digest == digest(signature)
167
+ #Check signature
168
+ expected = canonical_digest(hash)
169
+ signer = @directory.authorities[authority]
170
+ raise SecurityError, "Unknown signing authority #{authority}" unless signer
171
+ got = signer.public_decrypt(Encoding::Base64Cookie.load(signature))
172
+ unless (got == expected)
173
+ raise SecurityError, "Signature mismatch on global session cookie; tampering suspected"
174
+ end
166
175
  end
167
-
176
+
168
177
  #Check trust in signing authority
169
178
  unless @directory.trusted_authority?(authority)
170
179
  raise SecurityError, "Global sessions signed by #{authority} are not trusted"
@@ -2,10 +2,7 @@ module HasGlobalSession
2
2
  module Rails
3
3
  module ActionControllerInstanceMethods
4
4
  def self.included(base)
5
- if Configuration['integrated']
6
- base.alias_method_chain :session, :global_session
7
- end
8
-
5
+ base.alias_method_chain :session, :global_session
9
6
  base.before_filter :global_session_read_cookie
10
7
  base.before_filter :global_session_auto_renew
11
8
  base.after_filter :global_session_update_cookie
@@ -16,13 +13,14 @@ module HasGlobalSession
16
13
  end
17
14
 
18
15
  def session_with_global_session
19
- if global_session
16
+ if Configuration['integrated'] && @global_session
20
17
  unless @integrated_session &&
21
18
  (@integrated_session.local == session_without_global_session) &&
22
19
  (@integrated_session.global == @global_session)
23
20
  @integrated_session =
24
- IntegratedSession.new(session_without_global_session, global_session)
21
+ IntegratedSession.new(session_without_global_session, @global_session)
25
22
  end
23
+
26
24
  return @integrated_session
27
25
  else
28
26
  return session_without_global_session
@@ -35,9 +33,16 @@ module HasGlobalSession
35
33
  cookie = cookies[cookie_name]
36
34
 
37
35
  begin
36
+ cached_digest = session_without_global_session[:_session_gbl_valid_sig]
37
+
38
38
  #unserialize the global session from the cookie, or
39
- #initialize a new global session if cookie == nil
40
- @global_session = GlobalSession.new(directory, cookie)
39
+ #initialize a new global session if cookie == nil.
40
+ #
41
+ #pass along the cached trusted signature (if any) so the new object
42
+ #can skip the expensive RSA Decrypt operation.
43
+ @global_session = GlobalSession.new(directory, cookie, cached_digest)
44
+
45
+ session_without_global_session[:_session_gbl_valid_sig] = @global_session.signature_digest
41
46
  return true
42
47
  rescue Exception => e
43
48
  #silently recover from any error by initializing a new global session
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_global_session
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
4
+ hash: 49
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 3
10
- version: 0.9.3
9
+ - 5
10
+ version: 0.9.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tony Spataro
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-19 00:00:00 -07:00
18
+ date: 2010-07-20 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -98,6 +98,22 @@ dependencies:
98
98
  version: 0.8.6
99
99
  type: :development
100
100
  version_requirements: *id005
101
+ - !ruby/object:Gem::Dependency
102
+ name: actionpack
103
+ prerelease: false
104
+ requirement: &id006 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 15
110
+ segments:
111
+ - 2
112
+ - 1
113
+ - 2
114
+ version: 2.1.2
115
+ type: :development
116
+ version_requirements: *id006
101
117
  description: This plugin for Rails allows several web apps in an authentication domain to share session state, facilitating single sign-on in a distributed web app. It only provides session sharing and does not concern itself with authentication or replication of the user database.
102
118
  email: code@tracker.xeger.net
103
119
  executables: []