Commit 8f7acf49d55b45dbc448f40547d9087762263ddb
Finish JRuby support.
Signed-off-by: Coda Hale <coda.hale@gmail.com>Hongli Lai (Phusion) authored on 8/4/2009, 9:37:35 PM
Coda Hale committed on 8/12/2009, 9:54:49 PM
Parent: 13543432e645183e79ad4e626fa8f0de0d5c02bb
Files changed
Rakefile | changed |
ext/extconf.rb | changed |
lib/bcrypt.rb | changed |
Rakefile | ||
---|---|---|
@@ -14,9 +14,11 @@ | ||
14 | 14 | 'lib/**/*.rb', |
15 | 15 | 'spec/**/*.rb', |
16 | 16 | 'ext/*.c', |
17 | 17 | 'ext/*.h', |
18 | - 'ext/*.rb' | |
18 | + 'ext/*.rb', | |
19 | + 'ext/jruby/bcrypt_jruby/BCrypt.java', | |
20 | + 'ext/jruby/bcrypt_jruby/BCrypt.class' | |
19 | 21 | ] |
20 | 22 | CLEAN.include( |
21 | 23 | "ext/*.o", |
22 | 24 | "ext/*.bundle", |
@@ -80,14 +82,33 @@ | ||
80 | 82 | pkg.need_zip = true |
81 | 83 | pkg.need_tar = true |
82 | 84 | end |
83 | 85 | |
84 | -desc "Clean, then compile the extension." | |
85 | -task :compile => [:clean] do | |
86 | - Dir.chdir('ext') do | |
87 | - ruby "extconf.rb" | |
88 | - sh "make" | |
86 | +desc "Clean, then compile the extension that's native to the current Ruby compiler." | |
87 | +if RUBY_PLATFORM == "java" | |
88 | + task :compile => 'compile:jruby' | |
89 | +else | |
90 | + task :compile => 'compile:mri' | |
91 | +end | |
92 | + | |
93 | +namespace :compile do | |
94 | + desc "CLean, then compile all extensions" | |
95 | + task :all => [:mri, :jruby] | |
96 | + | |
97 | + desc "Clean, then compile the MRI extension" | |
98 | + task :mri => :clean do | |
99 | + Dir.chdir('ext') do | |
100 | + ruby "extconf.rb" | |
101 | + sh "make" | |
102 | + end | |
89 | 103 | end |
104 | + | |
105 | + desc "Clean, then compile the JRuby extension" | |
106 | + task :jruby => :clean do | |
107 | + Dir.chdir('ext/jruby/bcrypt_jruby') do | |
108 | + sh "javac BCrypt.java" | |
109 | + end | |
110 | + end | |
90 | 111 | end |
91 | 112 | |
92 | 113 | desc "Run a set of benchmarks on the compiled extension." |
93 | 114 | task :benchmark do |
ext/extconf.rb | ||
---|---|---|
@@ -1,5 +1,18 @@ | ||
1 | -require "mkmf" | |
2 | -dir_config("bcrypt_ext") | |
3 | -# enable this when we're feeling nitpicky | |
4 | -# CONFIG['CC'] << " -Wall " | |
5 | -create_makefile("bcrypt_ext") | |
1 | +if RUBY_PLATFORM == "java" | |
2 | + # Don't do anything when run in JRuby; this allows gem installation to pass. | |
3 | + # We need to write a dummy Makefile so that RubyGems doesn't think compilation | |
4 | + # failed. | |
5 | + File.open('Makefile', 'w') do |f| | |
6 | + f.puts "all:" | |
7 | + f.puts "\t@true" | |
8 | + f.puts "install:" | |
9 | + f.puts "\t@true" | |
10 | + end | |
11 | + exit 0 | |
12 | +else | |
13 | + require "mkmf" | |
14 | + dir_config("bcrypt_ext") | |
15 | + # enable this when we're feeling nitpicky | |
16 | + # CONFIG['CC'] << " -Wall " | |
17 | + create_makefile("bcrypt_ext") | |
18 | +end |
lib/bcrypt.rb | ||
---|---|---|
@@ -1,9 +1,15 @@ | ||
1 | 1 | # A wrapper for OpenBSD's bcrypt/crypt_blowfish password-hashing algorithm. |
2 | 2 | |
3 | -$: << "ext" | |
4 | -require "bcrypt_ext" | |
5 | -require "openssl" | |
3 | +if RUBY_PLATFORM == "java" | |
4 | + require 'java' | |
5 | + $CLASSPATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "ext", "jruby")) | |
6 | +else | |
7 | + $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "ext"))) | |
8 | + puts $LOAD_PATH | |
9 | + require "bcrypt_ext" | |
10 | + require "openssl" | |
11 | +end | |
6 | 12 | |
7 | 13 | # A Ruby library implementing OpenBSD's bcrypt()/crypt_blowfish algorithm for |
8 | 14 | # hashing passwords. |
9 | 15 | module BCrypt |
@@ -13,26 +19,34 @@ | ||
13 | 19 | class InvalidCost < StandardError; end # The cost parameter provided to bcrypt() is invalid. |
14 | 20 | class InvalidSecret < StandardError; end # The secret parameter provided to bcrypt() is invalid. |
15 | 21 | end |
16 | 22 | |
17 | - # A Ruby wrapper for the bcrypt() extension calls. | |
23 | + # A Ruby wrapper for the bcrypt() C extension calls and the Java calls. | |
18 | 24 | class Engine |
19 | 25 | # The default computational expense parameter. |
20 | 26 | DEFAULT_COST = 10 |
27 | + # The minimum cost supported by the algorithm. | |
28 | + MIN_COST = 4 | |
21 | 29 | # Maximum possible size of bcrypt() salts. |
22 | 30 | MAX_SALT_LENGTH = 16 |
23 | 31 | |
24 | - # C-level routines which, if they don't get the right input, will crash the | |
25 | - # hell out of the Ruby process. | |
26 | - private_class_method :__bc_salt | |
27 | - private_class_method :__bc_crypt | |
32 | + if RUBY_PLATFORM != "java" | |
33 | + # C-level routines which, if they don't get the right input, will crash the | |
34 | + # hell out of the Ruby process. | |
35 | + private_class_method :__bc_salt | |
36 | + private_class_method :__bc_crypt | |
37 | + end | |
28 | 38 | |
29 | 39 | # Given a secret and a valid salt (see BCrypt::Engine.generate_salt) calculates |
30 | 40 | # a bcrypt() password hash. |
31 | 41 | def self.hash_secret(secret, salt) |
32 | 42 | if valid_secret?(secret) |
33 | 43 | if valid_salt?(salt) |
34 | - __bc_crypt(secret.to_s, salt) | |
44 | + if RUBY_PLATFORM == "java" | |
45 | + Java.bcrypt_jruby.BCrypt.hashpw(secret.to_s, salt.to_s) | |
46 | + else | |
47 | + __bc_crypt(secret.to_s, salt) | |
48 | + end | |
35 | 49 | else |
36 | 50 | raise Errors::InvalidSalt.new("invalid salt") |
37 | 51 | end |
38 | 52 | else |
@@ -41,10 +55,18 @@ | ||
41 | 55 | end |
42 | 56 | |
43 | 57 | # Generates a random salt with a given computational cost. |
44 | 58 | def self.generate_salt(cost = DEFAULT_COST) |
45 | - if cost.to_i > 0 | |
46 | - __bc_salt(cost, OpenSSL::Random.random_bytes(MAX_SALT_LENGTH)) | |
59 | + cost = cost.to_i | |
60 | + if cost > 0 | |
61 | + if cost < MIN_COST | |
62 | + cost = MIN_COST | |
63 | + end | |
64 | + if RUBY_PLATFORM == "java" | |
65 | + Java.bcrypt_jruby.BCrypt.gensalt(cost) | |
66 | + else | |
67 | + __bc_salt(cost, OpenSSL::Random.random_bytes(MAX_SALT_LENGTH)) | |
68 | + end | |
47 | 69 | else |
48 | 70 | raise Errors::InvalidCost.new("cost must be numeric and > 0") |
49 | 71 | end |
50 | 72 | end |
Built with git-ssb-web