rotp 2.0.0 → 2.1.0

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.
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