Created
December 27, 2016 11:24
-
-
Save kaworu/1e117b0bb6993d5319cb1f8c2363d4c7 to your computer and use it in GitHub Desktop.
A simple doveadm(1) pw "replacement" for BLF-CRYPT only
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'https://rubygems.org' | |
gem 'bcrypt' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
% bundle install && bundle exec ruby doveadm-pw-bcrypt.rb -r 10 -s BLF-CRYPT