cram_md5 0.0.4
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/Gemfile +4 -0
- data/LICENSE +38 -0
- data/README.md +34 -0
- data/Rakefile +2 -0
- data/cram_md5.gemspec +29 -0
- data/lib/cram_md5/version.rb +3 -0
- data/lib/cram_md5.rb +129 -0
- metadata +78 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
Copyright (c) 2012 Thiago Coutinho
|
2
|
+
|
3
|
+
Written by
|
4
|
+
|
5
|
+
- Thiago Coutinho <thiago@osfeio.com>
|
6
|
+
|
7
|
+
Based on
|
8
|
+
|
9
|
+
- perl's Crypt::PasswdMD5 by Luis Munoz (lem@cantv.net)
|
10
|
+
- phyton's md5crypt.py by Michal Wallace http://www.sabren.com/
|
11
|
+
- /usr/src/libcrypt/crypt.c from FreeBSD 2.2.5-RELEASE
|
12
|
+
Many thanks to
|
13
|
+
- Ricardo Perez <riperezzz@gmail.com>
|
14
|
+
|
15
|
+
Version: 1.0 stable
|
16
|
+
Last edit: Tue, 13 September 2012 17:05:28 -0300 GMT
|
17
|
+
(after 7 years of phyton version... \o/ happy Birthday \o/)
|
18
|
+
|
19
|
+
USAGE
|
20
|
+
|
21
|
+
cryptedpassword = CramMd5::md5crypt_unix (password [, salt [, magicstring ])
|
22
|
+
apachepassword = CramMd5::md5crypt_apache (password [, salt])
|
23
|
+
|
24
|
+
DESCRIPTION
|
25
|
+
|
26
|
+
unix_md5_crypt() provides a crypt()-compatible interface to the
|
27
|
+
rather old MD5-based crypt() function found in modern operating systems
|
28
|
+
using old and solid libs.
|
29
|
+
|
30
|
+
It's based on the implementation found on FreeBSD 2.2.[56]-RELEASE and
|
31
|
+
contains the following license in it:
|
32
|
+
|
33
|
+
"THE BEER-WARE LICENSE" (Revision 42):
|
34
|
+
<thiago@osfeio.com> wrote this file based on the other descriptions. As long as
|
35
|
+
you retain this notice you can do whatever you want with this stuff. If we meet
|
36
|
+
some day, and you think this stuff is worth it, you can buy me a beer in return.
|
37
|
+
|
38
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# CramMd5
|
2
|
+
|
3
|
+
unix_md5_crypt() provides a crypt()-compatible interface to the
|
4
|
+
rather old MD5-based crypt() function found in modern operating systems
|
5
|
+
using old and solid libs.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'cram_md5'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install cram_md5
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
cryptedpassword = CramMd5::md5crypt_unix (password [, salt [, magicstring ])
|
24
|
+
|
25
|
+
apachepassword = CramMd5::md5crypt_apache (password [, salt])
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
34
|
+
6. Execure the "THE BEER-WARE LICENSE".
|
data/Rakefile
ADDED
data/cram_md5.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/cram_md5/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Thiago Coutinho"]
|
6
|
+
gem.email = ["thiago.coutinho@locaweb.com.br"]
|
7
|
+
gem.description = %q{
|
8
|
+
unix_md5_crypt() provides a crypt()-compatible interface to the
|
9
|
+
rather old MD5-based crypt() function found in modern operating systems
|
10
|
+
using old and solid libs.}
|
11
|
+
gem.summary = %q{ unix_md5_crypt CRAM-MD5 or Crypt MD5 }
|
12
|
+
gem.homepage = ""
|
13
|
+
|
14
|
+
gem.files = [
|
15
|
+
"Gemfile",
|
16
|
+
"LICENSE",
|
17
|
+
"README.md",
|
18
|
+
"Rakefile",
|
19
|
+
"cram_md5.gemspec",
|
20
|
+
"lib/cram_md5.rb",
|
21
|
+
"lib/cram_md5/version.rb"
|
22
|
+
]
|
23
|
+
|
24
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
25
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
26
|
+
gem.name = "cram_md5"
|
27
|
+
gem.require_paths = ["lib"]
|
28
|
+
gem.version = CramMd5::VERSION
|
29
|
+
end
|
data/lib/cram_md5.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
module CramMd5
|
5
|
+
MAGIC = '$1$'
|
6
|
+
ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
7
|
+
|
8
|
+
def self.to64(v, n)
|
9
|
+
ret = ''
|
10
|
+
while (n - 1 >= 0)
|
11
|
+
n = n - 1
|
12
|
+
|
13
|
+
ret = ret + ITOA64[v & 0x3f]
|
14
|
+
v = v >> 6
|
15
|
+
end
|
16
|
+
ret
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.apache_md5_crypt (pw, salt)
|
20
|
+
self.unix_md5_crypt(pw, salt, '$apr1$')
|
21
|
+
end
|
22
|
+
|
23
|
+
#@params [string] password
|
24
|
+
#@params [string] salt
|
25
|
+
#@params [string] magic
|
26
|
+
#@note For compare, use de original password and the salt of encrypted password.
|
27
|
+
#@return [string] crypt pass
|
28
|
+
|
29
|
+
def self.unix_md5_crypt(pw, salt="", magic=nil)
|
30
|
+
|
31
|
+
if magic==nil
|
32
|
+
magic = MAGIC
|
33
|
+
end
|
34
|
+
|
35
|
+
# Take care of the magic string if present
|
36
|
+
salt = salt[magic.length..-1] if salt[0..magic.length-1] == magic
|
37
|
+
|
38
|
+
# salt can have up to 8 characters:
|
39
|
+
salt = salt[0..7]
|
40
|
+
salt = rand_str(8) if salt == ""
|
41
|
+
|
42
|
+
ctx = pw + magic + salt
|
43
|
+
|
44
|
+
final = Digest::MD5.digest(pw + salt + pw)
|
45
|
+
|
46
|
+
pl = pw.length
|
47
|
+
while(pl>0)
|
48
|
+
if pl > 16
|
49
|
+
ctx = ctx + final[0..15]
|
50
|
+
else
|
51
|
+
ctx = ctx + final[0..pl-1]
|
52
|
+
end
|
53
|
+
pl -= 16
|
54
|
+
end
|
55
|
+
# Now the 'weird' xform (??)
|
56
|
+
|
57
|
+
i = pw.length
|
58
|
+
while(i>0)
|
59
|
+
if (i & 1) > 0
|
60
|
+
ctx = ctx + 0.chr #if ($i & 1) { $ctx->add(pack("C", 0)); }
|
61
|
+
else
|
62
|
+
ctx = ctx + pw[0]
|
63
|
+
end
|
64
|
+
i = i >> 1
|
65
|
+
end
|
66
|
+
|
67
|
+
final = Digest::MD5.digest(ctx)
|
68
|
+
|
69
|
+
# The following is supposed to make
|
70
|
+
# things run slower.
|
71
|
+
|
72
|
+
# my question: WTF???
|
73
|
+
|
74
|
+
(0..999).each do |i|
|
75
|
+
ctx1 = ''
|
76
|
+
if (i & 1) > 0
|
77
|
+
ctx1 = ctx1 + pw
|
78
|
+
else
|
79
|
+
ctx1 = ctx1 + final[0..15]
|
80
|
+
end
|
81
|
+
|
82
|
+
ctx1 = ctx1 + salt if (i % 3) > 0
|
83
|
+
|
84
|
+
|
85
|
+
ctx1 = ctx1 + pw if (i % 7) > 0
|
86
|
+
|
87
|
+
if (i & 1) > 0
|
88
|
+
ctx1 = ctx1 + final[0..15]
|
89
|
+
else
|
90
|
+
ctx1 = ctx1 + pw
|
91
|
+
end
|
92
|
+
|
93
|
+
final = Digest::MD5.digest(ctx1)
|
94
|
+
end
|
95
|
+
# Final xform
|
96
|
+
|
97
|
+
passwd = ''
|
98
|
+
|
99
|
+
passwd = passwd + self.to64( (final[0].ord.to_i << 16)|(final[6].ord.to_i << 8)|(final[12].ord.to_i),4)
|
100
|
+
|
101
|
+
passwd = passwd + self.to64((final[1].ord.to_i << 16)|(final[7].ord.to_i << 8)|(final[13].ord.to_i), 4)
|
102
|
+
|
103
|
+
passwd = passwd + self.to64((final[2].ord.to_i << 16)|(final[8].ord.to_i << 8)|(final[14].ord.to_i), 4)
|
104
|
+
|
105
|
+
passwd = passwd + self.to64((final[3].ord.to_i << 16)|(final[9].ord.to_i << 8)|(final[15].ord.to_i), 4)
|
106
|
+
|
107
|
+
passwd = passwd + self.to64((final[4].ord.to_i << 16)|(final[10].ord.to_i << 8)|(final[5].ord.to_i), 4)
|
108
|
+
|
109
|
+
passwd = passwd + self.to64((final[11].ord.to_i), 2)
|
110
|
+
|
111
|
+
magic + salt + '$' + passwd
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.rand_str(max_length = 32, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890')
|
115
|
+
|
116
|
+
chars_length = (chars.length - 1);
|
117
|
+
|
118
|
+
string = chars[rand(chars_length)];
|
119
|
+
i=0
|
120
|
+
while(string.length<max_length)
|
121
|
+
c = chars[rand(chars_length)];
|
122
|
+
|
123
|
+
string += c if (c != string[string.length - 1])
|
124
|
+
end
|
125
|
+
|
126
|
+
string
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cram_md5
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Thiago Coutinho
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-09-25 00:00:00 -03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: |-
|
23
|
+
|
24
|
+
unix_md5_crypt() provides a crypt()-compatible interface to the
|
25
|
+
rather old MD5-based crypt() function found in modern operating systems
|
26
|
+
using old and solid libs.
|
27
|
+
email:
|
28
|
+
- thiago.coutinho@locaweb.com.br
|
29
|
+
executables: []
|
30
|
+
|
31
|
+
extensions: []
|
32
|
+
|
33
|
+
extra_rdoc_files: []
|
34
|
+
|
35
|
+
files:
|
36
|
+
- Gemfile
|
37
|
+
- LICENSE
|
38
|
+
- README.md
|
39
|
+
- Rakefile
|
40
|
+
- cram_md5.gemspec
|
41
|
+
- lib/cram_md5.rb
|
42
|
+
- lib/cram_md5/version.rb
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: ""
|
45
|
+
licenses: []
|
46
|
+
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
hash: 3
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.7
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: unix_md5_crypt CRAM-MD5 or Crypt MD5
|
77
|
+
test_files: []
|
78
|
+
|