pelle-oauth 0.3.5 → 0.3.6

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/History.txt CHANGED
@@ -1,6 +1,8 @@
1
1
  == 0.3.6
2
2
 
3
3
  * Added -B CLI option to use the :body authentication scheme (Seth)
4
+ * Added :ca_file consumer option to allow consumer specific certificate override. (Pelle)
5
+ * Added a secure_equals in Helper to prevent timing attacks. (Pelle)
4
6
 
5
7
  == 0.3.5 2009-06-03
6
8
 
data/Rakefile CHANGED
@@ -1,35 +1,44 @@
1
- %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
1
+ %w[rubygems rake rake/clean fileutils].each { |f| require f }
2
2
  $LOAD_PATH << File.dirname(__FILE__) + '/lib'
3
3
  require 'oauth'
4
4
  require 'oauth/version'
5
5
 
6
- # Generate all the Rake tasks
7
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
8
- $hoe = Hoe.new('oauth', OAuth::VERSION) do |p|
9
- p.author = ['Pelle Braendgaard','Blaine Cook','Larry Halff','Jesse Clark','Jon Crosby', 'Seth Fitzsimmons']
10
- p.email = "oauth-ruby@googlegroups.com"
11
- p.description = "OAuth Core Ruby implementation"
12
- p.summary = p.description
13
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
14
- p.rubyforge_name = p.name # TODO this is default value
15
- p.url = "http://oauth.rubyforge.org"
6
+ begin
7
+ require 'hoe'
8
+ require 'newgem'
9
+ require 'rubigen'
10
+
11
+ # Generate all the Rake tasks
12
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
+ $hoe = Hoe.new('oauth', OAuth::VERSION) do |p|
14
+ p.author = ['Pelle Braendgaard','Blaine Cook','Larry Halff','Jesse Clark','Jon Crosby', 'Seth Fitzsimmons']
15
+ p.email = "oauth-ruby@googlegroups.com"
16
+ p.description = "OAuth Core Ruby implementation"
17
+ p.summary = p.description
18
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
19
+ p.rubyforge_name = p.name # TODO this is default value
20
+ p.url = "http://oauth.rubyforge.org"
16
21
 
17
- p.extra_deps = [
18
- ['ruby-hmac','>= 0.3.1']
19
- ]
20
- p.extra_dev_deps = [
21
- ['newgem', ">= #{::Newgem::VERSION}"],
22
- ['actionpack'],
23
- ['rack']
24
- ]
22
+ p.extra_deps = [
23
+ ['ruby-hmac','>= 0.3.1']
24
+ ]
25
+ p.extra_dev_deps = [
26
+ ['newgem', ">= #{::Newgem::VERSION}"],
27
+ ['actionpack'],
28
+ ['rack']
29
+ ]
25
30
 
26
- p.clean_globs |= %w[**/.DS_Store tmp *.log **/.*.sw? *.gem .config **/.DS_Store]
27
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
28
- p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
29
- p.rsync_args = '-av --delete --ignore-errors'
31
+ p.clean_globs |= %w[**/.DS_Store tmp *.log **/.*.sw? *.gem .config **/.DS_Store]
32
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
33
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
34
+ p.rsync_args = '-av --delete --ignore-errors'
35
+ end
36
+
37
+ require 'newgem/tasks' # load /tasks/*.rake
38
+ rescue LoadError
39
+ puts "hoe not available"
30
40
  end
31
41
 
32
- require 'newgem/tasks' # load /tasks/*.rake
33
42
  Dir['tasks/**/*.rake'].each { |t| load t }
34
43
 
35
44
  # TODO - want other tests/tasks run by default? Add them to the list
@@ -38,6 +38,9 @@ module OAuth
38
38
 
39
39
  # Default http method used for OAuth Token Requests (defaults to :post)
40
40
  :http_method => :post,
41
+
42
+ # Add a custom ca_file for consumer
43
+ # :ca_file => '/etc/certs.pem'
41
44
 
42
45
  :oauth_version => "1.0"
43
46
  }
@@ -278,8 +281,8 @@ module OAuth
278
281
 
279
282
  http_object.use_ssl = (our_uri.scheme == 'https')
280
283
 
281
- if CA_FILE
282
- http_object.ca_file = CA_FILE
284
+ if @options[:ca_file] || CA_FILE
285
+ http_object.ca_file = @options[:ca_file] || CA_FILE
283
286
  http_object.verify_mode = OpenSSL::SSL::VERIFY_PEER
284
287
  http_object.verify_depth = 5
285
288
  else
data/lib/oauth/helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'openssl'
2
2
  require 'base64'
3
+ require 'enumerator'
3
4
 
4
5
  module OAuth
5
6
  module Helper
@@ -70,9 +71,30 @@ module OAuth
70
71
  # convert into a Hash
71
72
  Hash[*params.flatten]
72
73
  end
73
-
74
+
75
+ # A secure version of equals meant to avoid timing attacks as specified here
76
+ # http://codahale.com/a-lesson-in-timing-attacks/
77
+ def secure_equals(a,b)
78
+ return a==b unless a.is_a?(String)&&b.is_a?(String)
79
+ result = 0
80
+ bytes(a).zip(bytes(b)).each do |x,y|
81
+ result |= (x ^ y)
82
+ end
83
+ (result == 0) && (a.length == b.length)
84
+ end
85
+
74
86
  def unescape(value)
75
87
  URI.unescape(value.gsub('+', '%2B'))
76
88
  end
89
+
90
+ # Creates a per byte enumerator for a string regardless of RUBY VERSION
91
+ def bytes(a)
92
+ return [] if a.nil?
93
+ if a.respond_to?(:bytes)
94
+ a.bytes
95
+ else
96
+ Enumerable::Enumerator.new(a, :each_byte)
97
+ end
98
+ end
77
99
  end
78
100
  end
@@ -55,7 +55,7 @@ module OAuth::Signature
55
55
  end
56
56
 
57
57
  def ==(cmp_signature)
58
- Base64.decode64(signature) == Base64.decode64(cmp_signature)
58
+ secure_equals(Base64.decode64(signature), Base64.decode64(cmp_signature))
59
59
  end
60
60
 
61
61
  def verify
@@ -9,7 +9,7 @@ module OAuth::Signature
9
9
  end
10
10
 
11
11
  def ==(cmp_signature)
12
- signature == escape(cmp_signature)
12
+ secure_equals(signature , escape(cmp_signature))
13
13
  end
14
14
 
15
15
  def signature_base_string
data/oauth.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{oauth}
5
- s.version = "0.3.5"
5
+ s.version = "0.3.6"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Pelle Braendgaard", "Blaine Cook", "Larry Halff", "Jesse Clark", "Jon Crosby", "Seth Fitzsimmons", "Matt Sanford"]
@@ -1,3 +1,4 @@
1
+ gem 'actionpack','2.2.2'
1
2
  require File.dirname(__FILE__) + '/test_helper.rb'
2
3
  require 'oauth/request_proxy/action_controller_request.rb'
3
4
  require 'action_controller'
@@ -1,19 +1,35 @@
1
+ # encoding: utf-8
1
2
  require File.dirname(__FILE__) + '/test_helper.rb'
2
3
 
3
4
  class TestOauth < Test::Unit::TestCase
4
-
5
+ include OAuth::Helper
6
+
5
7
  def test_parameter_escaping_kcode_invariant
6
8
  old = $KCODE
7
9
  begin
8
10
  %w(n N e E s S u U).each do |kcode|
9
11
  $KCODE = kcode
10
- assert_equal '%E3%81%82', OAuth::Helper.escape(''),
12
+ assert_equal '%E3%81%82', OAuth::Helper.escape(""),
11
13
  "Failed to correctly escape Japanese under $KCODE = #{kcode}"
12
- assert_equal '%C3%A9', OAuth::Helper.escape('é'),
14
+ assert_equal '%C3%A9', OAuth::Helper.escape("é"),
13
15
  "Failed to correctly escape e+acute under $KCODE = #{kcode}"
14
16
  end
15
17
  ensure
16
18
  $KCODE = old
17
19
  end
18
20
  end
21
+
22
+ def test_secure_equals
23
+ [nil,1,12345,"12345",'1','Hello'*45].each do |value|
24
+ assert secure_equals(value,value)
25
+ end
26
+ end
27
+
28
+ def test_not_secure_equals
29
+ a=[nil,1,12345,"12345",'1','Hello'*45]
30
+ a.zip(a.reverse).each do |a,b|
31
+ assert !secure_equals(a,b)
32
+ end
33
+ end
34
+
19
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pelle-oauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pelle Braendgaard