rotp 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c42bc8b1ce8ab11bb556cef750ae50187a6640d
4
- data.tar.gz: 165cbc7edb89427967f2777b7d8705b45486f18d
3
+ metadata.gz: ab533788e10594ef3290782dba5f044b4f6d259e
4
+ data.tar.gz: 39f4d7d06f29f05656374b5d2edef7d05f36fdd2
5
5
  SHA512:
6
- metadata.gz: ac2979aa19949bedb563e5fc407171efec7d80785e0246d19fed92bc78fca4b64eacdd1ef5c01a848f37c77a7d5bbbc03dc84e1e49d5f84bd55710ffc36b33af
7
- data.tar.gz: 8349669bdc320ff49ec55eb487eaaf38c352a52faa95bde3cfa8fde06b5ed7b889db670a254d2b2fd8b36286cb13bbaf03b86579466430e6b3d4850db1b0a770
6
+ metadata.gz: cfb56d25e3520f7d5875ce8d5d0a3b3d0a22cce6bb1c2b727ca5b95522b8a00cefe5ab43fe01b7d08038db675a902270662156dcffd3a0ed6d40f6bbe3375a66
7
+ data.tar.gz: a755331e53a9f06eb4627d820ec39db3092795dcd139c9e05dedaab7427e1c8c0ae1ae8c8fa21b23fdbb905c733206fb9decbc9d1ee36407abab2984d5f79c9c
data/.gitignore CHANGED
@@ -1,5 +1,4 @@
1
1
  *.gem
2
2
  .bundle
3
- Gemfile.lock
4
3
  .yardoc
5
4
  pkg/*
data/.travis.yml CHANGED
@@ -3,3 +3,5 @@ rvm:
3
3
  - 2.1.0
4
4
  - 2.0.0
5
5
  - 1.9.3
6
+ script:
7
+ - bundle exec rspec
data/CHANGELOG.md ADDED
@@ -0,0 +1,61 @@
1
+ ### Changelog
2
+
3
+ #### 2.1.0
4
+
5
+ - Add a CLI for generating OTP's mdp/rotp/pull/35
6
+
7
+ #### 2.0.0
8
+
9
+ - Move to only comparing string OTP's.
10
+
11
+ #### 1.7.0
12
+
13
+ - Move to only comparing string OTP's. See mdp/rotp/issues/32 - Moved to 2.0.0 - yanked from RubyGems
14
+
15
+ #### 1.6.1
16
+
17
+ - Remove deprecation warning in Ruby 2.1.0 (@ylansegal)
18
+ - Add Ruby 2.0 and 2.1 to Travis
19
+
20
+ #### 1.6.0
21
+
22
+ - Add verify_with_retries to HOTP
23
+ - Fix 'cgi' require and global DEFAULT_INTERVAL
24
+
25
+ #### 1.5.0
26
+
27
+ - Add support for "issuer" parameter on provisioning url
28
+ - Add support for "period/interval" parameter on provisioning url
29
+
30
+ #### 1.4.6
31
+
32
+ - Revert to previous Base32
33
+
34
+ #### 1.4.5
35
+
36
+ - Fix and test correct implementation of Base32
37
+
38
+ #### 1.4.4
39
+
40
+ - Fix issue with base32 decoding of strings in a length that's not a multiple of 8
41
+
42
+ #### 1.4.3
43
+
44
+ - Bugfix on padding
45
+
46
+ #### 1.4.2
47
+
48
+ - Better padding options (Pad the output with leading 0's)
49
+
50
+ #### 1.4.1
51
+
52
+ - Clean up drift logic
53
+
54
+ #### 1.4.0
55
+
56
+ - Added clock drift support via 'verify_with_drift' for TOTP
57
+
58
+ ####1.3.0
59
+
60
+ - Added support for Ruby 1.9.x
61
+ - Removed dependency on Base32
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
  gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,75 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rotp (2.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ celluloid (0.16.0)
10
+ timers (~> 4.0.0)
11
+ coderay (1.1.0)
12
+ diff-lcs (1.2.5)
13
+ ffi (1.9.6)
14
+ formatador (0.2.5)
15
+ guard (2.11.1)
16
+ formatador (>= 0.2.4)
17
+ listen (~> 2.7)
18
+ lumberjack (~> 1.0)
19
+ nenv (~> 0.1)
20
+ notiffany (~> 0.0)
21
+ pry (>= 0.9.12)
22
+ shellany (~> 0.0)
23
+ thor (>= 0.18.1)
24
+ guard-compat (1.2.0)
25
+ guard-rspec (4.5.0)
26
+ guard (~> 2.1)
27
+ guard-compat (~> 1.1)
28
+ rspec (>= 2.99.0, < 4.0)
29
+ hitimes (1.2.2)
30
+ listen (2.8.5)
31
+ celluloid (>= 0.15.2)
32
+ rb-fsevent (>= 0.9.3)
33
+ rb-inotify (>= 0.9)
34
+ lumberjack (1.0.9)
35
+ method_source (0.8.2)
36
+ nenv (0.1.1)
37
+ notiffany (0.0.3)
38
+ nenv (~> 0.1)
39
+ shellany (~> 0.0)
40
+ pry (0.10.1)
41
+ coderay (~> 1.1.0)
42
+ method_source (~> 0.8.1)
43
+ slop (~> 3.4)
44
+ rake (10.4.2)
45
+ rb-fsevent (0.9.4)
46
+ rb-inotify (0.9.5)
47
+ ffi (>= 0.5.0)
48
+ rspec (3.1.0)
49
+ rspec-core (~> 3.1.0)
50
+ rspec-expectations (~> 3.1.0)
51
+ rspec-mocks (~> 3.1.0)
52
+ rspec-core (3.1.7)
53
+ rspec-support (~> 3.1.0)
54
+ rspec-expectations (3.1.2)
55
+ diff-lcs (>= 1.2.0, < 2.0)
56
+ rspec-support (~> 3.1.0)
57
+ rspec-mocks (3.1.3)
58
+ rspec-support (~> 3.1.0)
59
+ rspec-support (3.1.2)
60
+ shellany (0.0.1)
61
+ slop (3.6.0)
62
+ thor (0.19.1)
63
+ timecop (0.7.1)
64
+ timers (4.0.1)
65
+ hitimes
66
+
67
+ PLATFORMS
68
+ ruby
69
+
70
+ DEPENDENCIES
71
+ guard-rspec (~> 4.5.0)
72
+ rake (~> 10.4.2)
73
+ rotp!
74
+ rspec (~> 3.1.0)
75
+ timecop (~> 0.7.1)
data/Guardfile ADDED
@@ -0,0 +1,14 @@
1
+ guard :rspec, cmd: 'bundle exec rspec --format progress' do
2
+ require "guard/rspec/dsl"
3
+ dsl = Guard::RSpec::Dsl.new(self)
4
+
5
+ # RSpec files
6
+ rspec = dsl.rspec
7
+ watch(rspec.spec_helper) { rspec.spec_dir }
8
+ watch(rspec.spec_support) { rspec.spec_dir }
9
+ watch(rspec.spec_files)
10
+
11
+ # Ruby files
12
+ ruby = dsl.ruby
13
+ dsl.watch_spec_files_for(ruby.lib_files)
14
+ end
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # The Ruby One Time Password Library
2
+
3
+ [![Build Status](https://secure.travis-ci.org/mdp/rotp.png)](https://travis-ci.org/mdp/rotp)
4
+ [![Gem Version](https://badge.fury.io/rb/rotp.svg)](https://rubygems.org/gems/rotp)
5
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/mdp/rotp/blob/master/LICENSE)
6
+
7
+ A ruby library for generating one time passwords (HOTP & TOTP) according to [RFC 4226](http://tools.ietf.org/html/rfc4226) and [RFC 6238](http://tools.ietf.org/html/rfc6238).
8
+
9
+ ROTP is compatible with the [Google Authenticator](https://github.com/google/google-authenticator) available for [Android](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2) and [iPhone](https://itunes.apple.com/en/app/google-authenticator/id388497605).
10
+
11
+ Many websites use this for [multi-factor authentication](https://www.youtube.com/watch?v=17rykTIX_HY), such as GMail, Facebook, Amazon EC2, WordPress, and Salesforce. You can find the whole [list here](https://en.wikipedia.org/wiki/Google_Authenticator#Usage).
12
+
13
+ ## Dependencies
14
+
15
+ * OpenSSL
16
+ * Ruby 1.9.3 or higher
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ gem install rotp
22
+ ```
23
+
24
+ ## Library Usage
25
+
26
+ ### Time based OTP's
27
+
28
+ ```ruby
29
+ totp = ROTP::TOTP.new("base32secret3232")
30
+ totp.now # => "492039"
31
+
32
+ # OTP verified for current time
33
+ totp.verify("492039") # => true
34
+ sleep 30
35
+ totp.verify("492039") # => false
36
+ ```
37
+
38
+ ### Counter based OTP's
39
+
40
+ ```ruby
41
+ hotp = ROTP::HOTP.new("base32secretkey3232")
42
+ hotp.at(0) # => "260182"
43
+ hotp.at(1) # => "055283"
44
+ hotp.at(1401) # => "316439"
45
+
46
+ # OTP verified with a counter
47
+ hotp.verify("316439", 1401) # => true
48
+ hotp.verify("316439", 1402) # => false
49
+ ```
50
+
51
+ ### Generating a Base32 Secret key
52
+
53
+ ```ruby
54
+ ROTP::Base32.random_base32 # returns a 16 character base32 secret. Compatible with Google Authenticator
55
+ ```
56
+
57
+ Note: The Base32 format conforms to [RFC 4648 Base32](http://en.wikipedia.org/wiki/Base32#RFC_4648_Base32_alphabet)
58
+
59
+ ### Google Authenticator Compatible URI's
60
+
61
+ Provisioning URI's generated by ROTP are compatible with the Google Authenticator App
62
+ to be scanned with the in-built QR Code scanner.
63
+
64
+ ```ruby
65
+ totp.provisioning_uri("alice@google.com") # => 'otpauth://totp/alice@google.com?secret=JBSWY3DPEHPK3PXP'
66
+ hotp.provisioning_uri("alice@google.com", 0) # => 'otpauth://hotp/alice@google.com?secret=JBSWY3DPEHPK3PXP&counter=0'
67
+ ```
68
+
69
+ This can then be rendered as a QR Code which can then be scanned and added to the users
70
+ list of OTP credentials.
71
+
72
+ #### Working example
73
+
74
+ Scan the following barcode with your phone, using Google Authenticator
75
+
76
+ ![QR Code for OTP](http://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP)
77
+
78
+ Now run the following and compare the output
79
+
80
+ ```ruby
81
+ require 'rubygems'
82
+ require 'rotp'
83
+ totp = ROTP::TOTP.new("JBSWY3DPEHPK3PXP")
84
+ p "Current OTP: #{totp.now}"
85
+ ```
86
+
87
+ ### Testing
88
+
89
+ ```bash
90
+ bundle install
91
+ bundle exec rspec
92
+ ```
93
+
94
+ ## Executable Usage
95
+
96
+ Once the rotp rubygem is installed on your system, you should be able to run the `rotp` executable
97
+ (if not, you might find trouble-shooting help [at this stackoverflow question](http://stackoverflow.com/a/909980)).
98
+
99
+ ```bash
100
+ # Try this to get an overview of the commands
101
+ rotp --help
102
+
103
+ # Examples
104
+ rotp --secret p4ssword # Generates a time-based one-time password
105
+ rotp --hmac --secret p4ssword --counter 42 # Generates a counter-based one-time password
106
+ ```
107
+
108
+ ## Contributors
109
+
110
+ Have a look at the [contributors graph](https://github.com/mdp/rotp/graphs/contributors) on Github.
111
+
112
+ ## License
113
+
114
+ MIT Copyright (C) 2011 by Mark Percival, see [LICENSE](https://github.com/mdp/rotp/blob/master/LICENSE) for details.
115
+
116
+ ## Other implementations
117
+
118
+ A list can be found at [Wikipedia](https://en.wikipedia.org/wiki/Google_Authenticator#Implementations).
data/Rakefile CHANGED
@@ -4,7 +4,6 @@ require "rspec/core/rake_task"
4
4
 
5
5
  RSpec::Core::RakeTask.new(:rspec) do |spec|
6
6
  spec.pattern = 'spec/**/*_spec.rb'
7
- spec.rspec_opts = ['-cfs --backtrace']
8
7
  end
9
8
 
10
9
  task :default => :rspec
data/bin/rotp ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.expand_path('../../lib', __FILE__)
4
+ require 'rotp'
5
+ require 'rotp/cli'
6
+
7
+ ROTP::CLI.new(File.basename(__FILE__), ARGV).run
@@ -0,0 +1,89 @@
1
+ require 'optparse'
2
+ require 'ostruct'
3
+
4
+ module ROTP
5
+ class Arguments
6
+
7
+ def initialize(filename, arguments)
8
+ @filename = filename
9
+ @arguments = Array(arguments)
10
+ end
11
+
12
+ def options
13
+ parse
14
+ options!
15
+ end
16
+
17
+ def to_s
18
+ parser.help + "\n"
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :arguments, :filename
24
+
25
+ def options!
26
+ @options ||= default_options
27
+ end
28
+
29
+ def default_options
30
+ OpenStruct.new time: true, counter: 0, mode: :time
31
+ end
32
+
33
+ def parse
34
+ return options!.mode = :help if arguments.empty?
35
+ parser.parse arguments
36
+
37
+ rescue OptionParser::InvalidOption => exception
38
+ options!.mode = :help
39
+ options!.warnings = red(exception.message + '. Try --help for help.')
40
+ end
41
+
42
+ def parser
43
+ OptionParser.new do |parser|
44
+ parser.banner = ''
45
+ parser.separator green(' Usage: ') + bold("#{filename} [options]")
46
+ parser.separator ''
47
+ parser.separator green ' Examples: '
48
+ parser.separator ' ' + bold("#{filename} --secret p4ssword") + ' # Generates a time-based one-time password'
49
+ parser.separator ' ' + bold("#{filename} --hmac --secret p4ssword --counter 42") + ' # Generates a counter-based one-time password'
50
+ parser.separator ''
51
+ parser.separator green ' Options:'
52
+
53
+ parser.on('-s', '--secret [SECRET]', 'The shared secret') do |secret|
54
+ options!.secret = secret
55
+ end
56
+
57
+ parser.on('-c', '--counter [COUNTER]', 'The counter for counter-based hmac OTP') do |counter|
58
+ options!.counter = counter.to_i
59
+ end
60
+
61
+ parser.on('-t', '--time', 'Use time-based OTP according to RFC 6238 (default)') do
62
+ options!.mode = :time
63
+ end
64
+
65
+ parser.on('-m', '--hmac', 'Use counter-based OTP according to RFC 4226') do
66
+ options!.mode = :hmac
67
+ end
68
+
69
+ parser.on_tail('-h', '--help', 'Show this message') do
70
+ options!.mode = :help
71
+ end
72
+ end
73
+ end
74
+
75
+ def bold(string)
76
+ "\033[1m#{string}\033[22m"
77
+ end
78
+
79
+ def green(string)
80
+ "\033[32m#{string}\033[0m"
81
+ end
82
+
83
+ def red(string)
84
+ "\033[31m#{string}\033[0m"
85
+ end
86
+
87
+ end
88
+ end
89
+
data/lib/rotp/cli.rb ADDED
@@ -0,0 +1,56 @@
1
+ require 'rotp/arguments'
2
+
3
+ module ROTP
4
+ class CLI
5
+ attr_reader :filename, :argv
6
+
7
+ def initialize(filename, argv)
8
+ @filename = filename
9
+ @argv = argv
10
+ end
11
+
12
+ def run
13
+ puts output
14
+ end
15
+
16
+ def errors
17
+ if [:time, :hmac].include?(options.mode)
18
+ if options.secret.to_s == ''
19
+ red 'You must also specify a --secret. Try --help for help.'
20
+ elsif options.secret.to_s.chars.any? { |c| ROTP::Base32::CHARS.index(c.downcase) == nil }
21
+ red 'Secret must be in RFC4648 Base32 format - http://en.wikipedia.org/wiki/Base32#RFC_4648_Base32_alphabet'
22
+ end
23
+ elsif options.mode == :hmac && options.counter.to_i < 0
24
+ red 'You must also specify a --counter. Try --help for help.'
25
+ end
26
+ end
27
+
28
+ def output
29
+ return options.warnings if options.warnings
30
+ return errors if errors
31
+ return arguments.to_s if options.mode == :help
32
+
33
+ if options.mode == :time
34
+ ROTP::TOTP.new(options.secret).now
35
+ elsif options.mode == :hmac
36
+ ROTP::HOTP.new(options.secret).at options.counter
37
+
38
+ else
39
+ fail NotImplementedError
40
+ end
41
+ end
42
+
43
+ def arguments
44
+ @arguments ||= ROTP::Arguments.new(filename, argv)
45
+ end
46
+
47
+ def options
48
+ arguments.options
49
+ end
50
+
51
+ def red(string)
52
+ "\033[31m#{string}\033[0m"
53
+ end
54
+
55
+ end
56
+ end