has_global_session 0.9.3 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []