From 7674dd1e3cd345e280df32b7fb86621940582d72 Mon Sep 17 00:00:00 2001 From: nishiki Date: Thu, 11 Jul 2013 00:03:27 +0200 Subject: [PATCH] the rewrite in ruby continue --- manage-password.rb | 209 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 189 insertions(+), 20 deletions(-) diff --git a/manage-password.rb b/manage-password.rb index c3bb496..7ef95aa 100755 --- a/manage-password.rb +++ b/manage-password.rb @@ -1,22 +1,32 @@ #!/usr/bin/ruby +# author: nishiki +# mail: nishiki@yaegashi.fr +# info: a simple script who manage your passwords + require 'rubygems' require 'gpgme' +require 'csv' -FILE_GPG = './pass.gpg' -KEY = 'adrien.waksberg@believedigital.com' -FILE_PWD = './tmp_passwd' -TIMEOUT_PWD = 10 +FILE_GPG = '/home/nishiki/.password-manager.gpg' +KEY = 'nishiki@yaegashi.fr' +FILE_PWD = '/tmp/.password-manager.pwd' +TIMEOUT_PWD = 300 class ManagePasswd - ID = 0 - TYPE = 1 - SERVER = 2 - LOGIN = 3 - PASSWD = 4 - PORT = 5 - COMMENT = 6 + ID = 0 + TYPE = 1 + SERVER = 2 + LOGIN = 3 + PASSWORD = 4 + PORT = 5 + COMMENT = 6 + # Constructor + # @args: key -> + # file_gpg -> + # file_pwd -> + # timeout_pwd -> def initialize(key, file_gpg, file_pwd, timeout_pwd=300) @key = key @file_gpg = file_gpg @@ -24,14 +34,17 @@ class ManagePasswd @timeout_pwd = timeout_pwd if File.exist?(@file_gpg) - self.decrypt() + if not self.decrypt() + exit 2 + end else @data = "" end end + # Decrypt a gpg file + # @rtrn: true if data is decrypted def decrypt() - if File.exist?(@file_pwd) && File.stat(@file_pwd).mtime.to_i + @timeout_pwd < Time.now.to_i File.delete(@file_pwd) end @@ -39,23 +52,179 @@ class ManagePasswd begin passwd = IO.read(@file_pwd) rescue - puts "Password GPG: " - passwd = gets - file_pwd = File.new(@file_pwd, 'w') + print "Password GPG: " + passwd = $stdin.gets + file_pwd = File.new(@file_pwd, 'w+') file_pwd << passwd file_pwd.close + File.chmod(0600, @file_pwd) end - crypto = GPGME::Crypto.new(:armor => true) - @data = crypto.decrypt(IO.read(@file_gpg), :password => passwd).read + begin + crypto = GPGME::Crypto.new(:armor => true) + @data = crypto.decrypt(IO.read(@file_gpg), :password => passwd).read + return true + rescue + puts "Your passphrase is probably wrong!" + File.delete(@file_pwd) + + return false + end end + # Encrypt a file def encrypt() - crypto = GPGME::Crypto.new(:armor => true) - crypto.encrypt(@data, :recipients => @key, :output => @file_gpg) + begin + crypto = GPGME::Crypto.new(:armor => true) + file_gpg = File.open(@file_gpg, 'w+') + crypto.encrypt(@data, :recipients => @key, :output => file_gpg) + file_gpg.close + + return true + rescue + puts "Error during the encrypting file" + return false + end + end + + # Search in some csv data + # @args: search -> the string to search + # type -> the connection type (ssh, web, other) + # @rtrn: a list with the resultat of the search + def search(search, type=nil) + result = Array.new() + @data.lines do |line| + row = line.parse_csv + if line =~ /^.*#{search}.*$/ + if type.nil? || type.eql?(row[TYPE]) + result.push(row) + end + end + end + + return result end + # Display the connections informations for a server + def display(search, type='') + result = self.search(search, type) + + if result.length > 0 + result.each do |r| + puts "# --------------------" + puts "# Id: #{r[ID]}" + puts "# Server: #{r[SERVER]}" + puts "# Type: #{r[TYPE]}" + puts "# Login: #{r[LOGIN]}" + puts "# Password: #{r[PASSWORD]}" + puts "# Port: #{r[PORT]}" + puts "# Comment: #{r[COMMENT]}" + end + + return true + else + puts "Nothing result!" + return false + end + end + + # Add a new item + def add() + row = Array.new() + puts "# Add a new password" + puts "# --------------------" + row[ID] = Time.now.to_i.to_s(16) + print "Enter the server name or ip: " + row[SERVER] = gets.chomp + print "Enter the type of connection (ssh, web, other): " + row[TYPE] = gets.chomp + print "Enter the login connection: " + row[LOGIN] = gets.chomp + print "Enter the the password: " + row[PASSWORD] = gets.chomp + print "Enter the connection port (optinal): " + row[PORT] = gets.chomp + print "Enter a comment (optinal): " + row[COMMENT] = gets.chomp + + @data << "#{row.join(',')}\n" + end + + # Connect to ssh && display the password + # @args: search -> + def ssh(search) + result = self.search(search, 'ssh') + + if result.length > 0 + result.each do |r| + server = r[SERVER] + login = r[LOGIN] + port = r[PORT] + passwd = r[PASSWORD] + + if port.empty? + port = 22 + end + + if passwd.empty? + system("#{passwd} ssh #{login}@#{server} -p #{port}") + else + system("sshpass -p #{passwd} ssh #{login}@#{server} -p #{port}") + end + end + + return true + else + puts "Nothing result!" + return false + end + end + + # Display help + def help() + puts "# HELP" + puts "# --------------------" + puts "Add a new item: -a" + puts "Update an item: -u ID" + puts "Remove an item: -r ID" + puts "Show a item: -d search [type]" + puts "Connect ssh: -s search" + end + end manage = ManagePasswd.new(KEY, FILE_GPG, FILE_PWD) +num_argv = ARGV.length + +# Display the item's informations +if num_argv >= 2 && ARGV[0] == '-d' + if num_argv == 3 + manage.display(ARGV[1], ARGV[2]) + else + manage.display(ARGV[1]) + end + +# Remove an item +elsif num_argv == 2 && ARGV[0] == '-r' + manage.remove(ARGV[1]) + manage.encrypt() + +# Update an item +elsif num_argv == 2 && ARGV[0] == '-u' + manage.update(ARGV[1]) + manage.encrypt() + +# Connect to ssh +elsif num_argv == 2 && ARGV[0] == '-s' + manage.ssh(ARGV[1]) + +# Add a new item +elsif num_argv == 1 && ARGV[0] == '-a' + manage.add() + manage.encrypt() + +# Display help +else + manage.help() +end