ttoken 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f57d2d3a74e0441e24f73e7776033882771c2710d8e57979e78d7ccd859f903e
4
+ data.tar.gz: 604f0afb5e97d18bf223d41dc764bd94597ab23c46d89eacb59b1b4793696fcb
5
+ SHA512:
6
+ metadata.gz: 5b4999a535b8fc61cc4cf3749c1099b46a7c73a8fe18cec75ab6a28c7e618a640e03860fb39c5b389bccb26d3eff39cec1fe7f676d58e73cdb0f81d938e2736b
7
+ data.tar.gz: 22581b23450161e2db3fbbb6d83cfaa81b63aef06ee1ec958540f0ce7200e193cb62fd00af24318efc020bf2bdac4db6d260a5a731f2fe1b1d300e12a5e5346c
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ttoken.gemspec
4
+ gemspec
5
+
@@ -0,0 +1,23 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.7.0)
5
+ public_suffix (>= 2.0.2, < 5.0)
6
+ fileutils (1.4.1)
7
+ openssl (2.2.0)
8
+ public_suffix (4.0.5)
9
+ rotp (6.0.0)
10
+ addressable (~> 2.7)
11
+ yaml (0.1.0)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ fileutils
18
+ openssl
19
+ rotp
20
+ yaml
21
+
22
+ BUNDLED WITH
23
+ 2.1.4
@@ -0,0 +1,52 @@
1
+ # Ttoken
2
+
3
+ Ttoken is a command-line program to generate time-based token/OTP.
4
+
5
+ Apart from generating time-based OTP, it provides the feature of creating pin+token and copies it to the clipboard so that user can enter it anywhere by just the click of Ctrl+v.
6
+
7
+ ## Installation
8
+
9
+ ```ruby
10
+ # yum install ruby rubygems
11
+
12
+ # gem install ttoken
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ Gem provides the executable command-line program - ttoken.
18
+
19
+ 1) To encrypt and save your password/pin in ttoken use the below command.
20
+
21
+ ```ruby
22
+ # ttoken --encrypt
23
+ ```
24
+
25
+ 2) Create the file `/etc/ttoken/ttoken.yml` and enter the below content.
26
+
27
+ ```ruby
28
+ # Issuer - The site or app you are creating the OTP
29
+ :issuer: 'Red Hat'
30
+
31
+ # Time-based token provided by issuer
32
+ :token: "1234abcdxyz"
33
+
34
+ # Enable pin+token
35
+ :pinplustoken: yes
36
+
37
+ ```
38
+ Make sure you change the issuer and token.
39
+
40
+
41
+
42
+ 3) Running the command will generate pin+token and will copy it to the clipboard.
43
+
44
+
45
+ ```ruby
46
+ # ttoken
47
+ ```
48
+
49
+ ## Contributing
50
+
51
+ Bug reports and pull requests are welcome on GitHub at https://github.com/patilsuraj767/ttoken.
52
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
4
+
5
+ require 'ttoken'
6
+
7
+ CONFIG_FILE = '/etc/ttoken/ttoken.yml'.freeze
8
+ ENCRYPTION_KEY_FILE = File.expand_path('~/.ttoken/ttoken_encryption_key.yml')
9
+
10
+ Ttoken.setup
11
+ Ttoken.run
12
+
13
+
14
+
@@ -0,0 +1,8 @@
1
+ # Enable pin+token
2
+ :pinplustoken: yes
3
+
4
+ # Issuer - The site or app you are creating the OTP
5
+ :issuer: 'Red Hat'
6
+
7
+ # Time-based token provided by issuer
8
+ :token: '1234abcdxyz'
@@ -0,0 +1,54 @@
1
+ require "ttoken/version"
2
+ require 'rotp'
3
+ require 'clipboard'
4
+ require 'io/console'
5
+
6
+ module Ttoken
7
+ require 'ttoken/config'
8
+ require 'ttoken/encrypt'
9
+ require 'ttoken/store'
10
+
11
+ class << self
12
+ attr_accessor :config
13
+
14
+ def setup
15
+ self.config = Config.new
16
+ end
17
+
18
+ def run
19
+ encrypt = Encrypt.new
20
+ if ARGV.length > 0 && ARGV[0] == '--encrypt'
21
+ pin = STDIN.getpass("Password/Pin:")
22
+ encrypted_pin = encrypt.encrypt_pin(pin)
23
+ Store.save_password(encrypted_pin)
24
+ else
25
+ token = generate_token(config.token, config.issuer)
26
+ if config.pinplustoken
27
+ password = Store.retrive_password
28
+ decrypted_pin = encrypt.decrypt_pin(password)
29
+ send_to_clipboard(decrypted_pin + token)
30
+ else
31
+ send_to_clipboard(token)
32
+ end
33
+ end
34
+ end
35
+
36
+ def generate_token(token, issuer)
37
+ begin
38
+ ROTP::TOTP.new(token, issuer: issuer).now
39
+ rescue StandardError => e
40
+ raise " \nSomething went wrong. Please check if all parameters in /etc/ttoken/ttoken.yml are correct.\n Error: #{e.message}"
41
+ end
42
+ end
43
+
44
+ def send_to_clipboard(text)
45
+ begin
46
+ system("echo -n #{text} | xclip -selection clipboard")
47
+ puts 'Data copied to clipboard. Ready to paste.'
48
+ rescue StandardError => e
49
+ raise "Problem in copying data to clipboard. Error: #{e.message}"
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,34 @@
1
+ require 'yaml'
2
+ module Ttoken
3
+ class Config
4
+ attr_accessor :config_file, :token, :issuer, :pinplustoken
5
+
6
+ def initialize
7
+ @config_file = config_file_path
8
+ @options = load_config
9
+ @token = @options.fetch(:token, nil)
10
+ @issuer = @options.fetch(:issuer, nil)
11
+ @pinplustoken = @options.fetch(:pinplustoken, false)
12
+ end
13
+
14
+ def config_file_path
15
+ File.exist?(CONFIG_FILE) ? CONFIG_FILE : File.join(source_path, 'config/ttoken.yml')
16
+ end
17
+
18
+ def load_config
19
+ if File.exist?(config_file)
20
+ YAML.load(File.open(config_file)) || {}
21
+ else
22
+ puts "Config file #{config_file} not found, using default configuration"
23
+ {}
24
+ end
25
+ rescue StandardError => e
26
+ raise "Couldn't load configuration file. Error: #{e.message}"
27
+ end
28
+
29
+ def source_path
30
+ File.expand_path('../../..', __FILE__)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ require 'openssl'
2
+ class Encrypt
3
+ CIPHER = OpenSSL::Cipher.new('aes-256-cbc')
4
+
5
+ def encrypt_pin(pin)
6
+ if is_encryptable?(pin)
7
+ cipher = CIPHER.encrypt
8
+ cipher.key = encryption_key
9
+ s = cipher.update(pin) + cipher.final
10
+ s.unpack('H*')[0].upcase
11
+ end
12
+ end
13
+
14
+ def decrypt_pin(pin)
15
+ if is_decryptable?(pin)
16
+ cipher = CIPHER.decrypt
17
+ cipher.key = encryption_key
18
+ s = [pin].pack("H*").unpack("C*").pack("c*")
19
+ begin
20
+ cipher.update(s) + cipher.final
21
+ rescue StandardError => e
22
+ raise "\n Problem in decrypting password. To resolve the issue encrypt and save the password again using command # ttoken --encrypt. \n Error: #{e.message}"
23
+ end
24
+ end
25
+ end
26
+
27
+ def is_encryptable?(str)
28
+ !encryption_key.nil? && !str.nil?
29
+ end
30
+
31
+ def is_decryptable?(str)
32
+ !encryption_key.nil? && !str.nil?
33
+ end
34
+
35
+ def encryption_key
36
+ if File.exist?(ENCRYPTION_KEY_FILE)
37
+ Store.retrive_encryption_key
38
+ else
39
+ key = CIPHER.random_key
40
+ Store.save_encryption_key(key)
41
+ key
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ require 'yaml'
2
+ class Store
3
+ PASSWORD_FILE = File.expand_path('~/.ttoken/ttoken.yml')
4
+
5
+ def self.save_password(password)
6
+ create_dir
7
+ data = {password: password}
8
+ begin
9
+ File.write(PASSWORD_FILE, data.to_yaml)
10
+ puts 'Password saved successfully. Use command #ttoken to generate pin+token'
11
+ rescue StandardError => e
12
+ raise "Unable to write password file. Error: #{e.message}"
13
+ end
14
+ end
15
+
16
+ def self.retrive_password
17
+ if File.exist?(PASSWORD_FILE)
18
+ pf = YAML.load(File.read(PASSWORD_FILE))
19
+ pf[:password]
20
+ else
21
+ puts 'Password file does not exits. Save the password/pin using command # ttoken --encrypt'
22
+ exit 2
23
+ end
24
+ end
25
+
26
+ def self.retrive_encryption_key
27
+ if File.exist?(ENCRYPTION_KEY_FILE)
28
+ pf = YAML.load(File.read(ENCRYPTION_KEY_FILE))
29
+ pf[:encryption_key]
30
+ end
31
+ end
32
+
33
+ def self.save_encryption_key(encryption_key)
34
+ create_dir
35
+ data = {encryption_key: encryption_key}
36
+ File.write(ENCRYPTION_KEY_FILE, data.to_yaml)
37
+ end
38
+
39
+ def self.create_dir
40
+ dir = File.expand_path('~/.ttoken')
41
+ Dir.mkdir(dir) unless Dir.exist?(dir)
42
+ end
43
+
44
+ end
@@ -0,0 +1,3 @@
1
+ module Ttoken
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'lib/ttoken/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "ttoken"
5
+ spec.version = Ttoken::VERSION
6
+ spec.authors = ["Suraj Patil"]
7
+ spec.email = ["patilsuraj767@gmail.com"]
8
+
9
+ spec.summary = %q{ttoken is a command line utility to generate time based token/otp.}
10
+ spec.homepage = "https://github.com/patilsuraj767/ttoken"
11
+
12
+ # Specify which files should be added to the gem when it is released.
13
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
14
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
15
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|images)/}) }
16
+ end
17
+
18
+ spec.executables = ['ttoken']
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'rotp', '5.1.0'
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ttoken
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Suraj Patil
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rotp
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 5.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.0
27
+ description:
28
+ email:
29
+ - patilsuraj767@gmail.com
30
+ executables:
31
+ - ttoken
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - Gemfile
37
+ - Gemfile.lock
38
+ - README.md
39
+ - bin/ttoken
40
+ - config/ttoken.yml.example
41
+ - lib/ttoken.rb
42
+ - lib/ttoken/config.rb
43
+ - lib/ttoken/encrypt.rb
44
+ - lib/ttoken/store.rb
45
+ - lib/ttoken/version.rb
46
+ - ttoken.gemspec
47
+ homepage: https://github.com/patilsuraj767/ttoken
48
+ licenses: []
49
+ metadata: {}
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubyforge_project:
66
+ rubygems_version: 2.7.6.2
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: ttoken is a command line utility to generate time based token/otp.
70
+ test_files: []