Skip to content

Instantly share code, notes, and snippets.

@kaworu
Created December 27, 2016 11:24
Show Gist options
  • Save kaworu/1e117b0bb6993d5319cb1f8c2363d4c7 to your computer and use it in GitHub Desktop.
Save kaworu/1e117b0bb6993d5319cb1f8c2363d4c7 to your computer and use it in GitHub Desktop.
A simple doveadm(1) pw "replacement" for BLF-CRYPT only
#!/usr/bin/env ruby
# encoding: UTF-8
require 'bcrypt'
require 'optparse'
# see https://stackoverflow.com/questions/2338889/how-to-hide-password-input-from-terminal-in-ruby-script/11765329#11765329
require 'io/console'
options = {
:cost => 5, # default, like doveadm
:scheme => 'BLF-CRYPT', # default, only one actually implemented
:password => nil,
}
OptionParser.new do |opts|
opts.banner = "usage: #$0 [options]"
opts.on("-r ROUNDS", "number of rounds") do |r|
n = r.to_i
raise ArgumentError.new("#{r}: invalid number of round") unless n.between?(4, 31)
options[:cost] = n
end
opts.on("-s SCHEME", "crypt scheme (only BLF-CRYPT is supported)") do |s|
raise ArgumentError.new("#{s}: invalid scheme") unless s == 'BLF-CRYPT'
end
opts.on("-p password", "pass the password on the command line (insecure!)") do |p|
options[:password] = p
end
end.parse!
def interactive?
STDIN.isatty
end
3.times do
break if options[:password]
STDERR.print 'Enter new password: ' if interactive?
password = (interactive? ? STDIN.noecho(&:gets) : STDIN.gets)
STDERR.puts if interactive?
STDERR.print 'Retype new password: ' if interactive?
repassword = (interactive? ? STDIN.noecho(&:gets) : STDIN.gets)
STDERR.puts if interactive?
if not password or not repassword
# NOTE: doveadm behaviour, crypt an empty password when password or
# repassword could not be read.
options[:password] = ''
elsif password.chomp! == repassword.chomp!
options[:password] = password
else
STDERR.puts "Error: Passwords don't match!"
# NOTE: doveadm behaviour, crypt an empty password when password and
# repassword missmatch and it is not an interactive session.
options[:password] = '' unless interactive?
end
end
exit 1 unless options[:password]
bcrypted = BCrypt::Password.create(options[:password], cost: options[:cost])
STDOUT.printf "{%s}%s\n", options[:scheme], bcrypted.to_s
source 'https://rubygems.org'
gem 'bcrypt'
@kaworu
Copy link
Author

kaworu commented Dec 27, 2016

% bundle install && bundle exec ruby doveadm-pw-bcrypt.rb -r 10 -s BLF-CRYPT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment