Class: Mkpasswd

Inherits:
Object
  • Object
show all
Defined in:
lib/mkpasswd.rb,
lib/mkpasswd/version.rb

Constant Summary collapse

HASHERS =
{
    'sha-512' => UnixCrypt::SHA512,
    'sha-256' => UnixCrypt::SHA256,
    'md5'     => UnixCrypt::MD5,
    'des'     => UnixCrypt::DES
}
VERSION =
'0.1.0'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Mkpasswd

Returns a new instance of Mkpasswd.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/mkpasswd.rb', line 21

def initialize(args)
  self.options = OpenStruct.new
  options.hashmethod = 'des'
  options.hasher     = HASHERS[options.hashmethod]

  OptionParser.new do |opts|
    opts.banner = "Usage: #{File.basename $0} [options] [PASSWORD [SALT]]"
    opts.separator 'Encrypts password using the unix-crypt gem with CLI compatible with mkpasswd utility from whois package.'
    opts.separator ''
    opts.separator 'Options:'

    opts.on('-m', '--method=METHOD', String, 'Set hash algorithm [sha-512 (default), sha-256, md5, des]') do |hasher|
      if hasher.to_s == 'help'
        puts 'Available methods:'
        puts HASHERS.keys
        exit
      end
      options.hashmethod = hasher.to_s
      options.hasher     = HASHERS[options.hashmethod]
      raise 'Invalid hash algorithm for -m/--method' if options.hasher.nil?
    end

    opts.on('-S', '--salt [SALT]', String, 'Provide hash salt') do |salt|
      raise 'Invalid salt for -S/--salt' if salt.nil?
      options.salt = salt
    end

    opts.on('-R', '--rounds [ROUNDS]', Integer, 'Set number of hashing rounds (SHA256/SHA512 only)') do |rounds|
      raise 'Invalid hashing rounds for -R/--rounds' if rounds.nil? || rounds.to_i <= 0
      options.rounds = rounds
    end

    opts.on_tail('-h', '--help', 'Show this message') do
      puts opts
      exit
    end

    opts.on_tail('-V', '--version', 'Show version') do
      puts Mkpasswd::VERSION
      exit
    end
  end.parse!(ARGV)

  options.password = ARGV.shift
  if options.password
    $0 = $0 # this invocation will get rid of the command line arguments from the process list
  else
    options.password = ask_password
  end
  options.salt = ARGV.shift  unless options.salt

  saltsize = options.salt.to_s.bytesize
  if saltsize > 0 && ( saltsize < 8 || saltsize > 16 )
    raise "Wrong salt length: #{saltsize} bytes when 8 <= n <= 16 expected."
  end
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



12
13
14
# File 'lib/mkpasswd.rb', line 12

def options
  @options
end

Instance Method Details

#ask_noecho(message) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/mkpasswd.rb', line 82

def ask_noecho(message)
  $stderr.print message
  if $no_io_console
    begin
      `stty -echo`
      result = gets
    ensure
      `stty echo`
    end
  else
    result = $stdin.noecho(&:gets)
  end
  $stderr.puts
  result
end

#ask_passwordObject



98
99
100
101
102
103
# File 'lib/mkpasswd.rb', line 98

def ask_password
  password = ask_noecho("Enter password: ")
  twice    = ask_noecho("Verify password: ")
  raise "Passwords don't match" if password != twice
  password.chomp!
end

#execute!Object



78
79
80
# File 'lib/mkpasswd.rb', line 78

def execute!
  puts options.hasher.build(options.password, options.salt, options.rounds)
end