mirror of
https://github.com/nishiki/manage-password.git
synced 2025-02-17 08:30:04 +00:00
first sync work :)
This commit is contained in:
parent
bc276f23c1
commit
8b86040af0
5 changed files with 248 additions and 48 deletions
19
lib/Cli.rb
19
lib/Cli.rb
|
@ -8,9 +8,11 @@ require 'highline/import'
|
|||
require 'pathname'
|
||||
require 'readline'
|
||||
require 'i18n'
|
||||
require 'yaml'
|
||||
|
||||
require "#{APP_ROOT}/lib/MPW.rb"
|
||||
require "#{APP_ROOT}/lib/MPWConfig.rb"
|
||||
require "#{APP_ROOT}/lib/Sync.rb"
|
||||
|
||||
class Cli
|
||||
|
||||
|
@ -29,6 +31,23 @@ class Cli
|
|||
puts "#{I18n.t('cli.display.error')}: #{@mpw.error_msg}"
|
||||
exit 2
|
||||
end
|
||||
|
||||
@sync = Sync.new()
|
||||
if @config.sync_host.nil? || @config.sync_port.nil?
|
||||
@sync.disable()
|
||||
elsif !@sync.connect(@config.sync_host, @config.sync_port, @config.key, @config.sync_pwd, @config.sync_suffix)
|
||||
puts "#{I18n.t('cli.sync.not_connect')}:\n#{@sync.error_msg}"
|
||||
else
|
||||
begin
|
||||
@mpw.sync(@sync.get(@passwd), @config.last_update)
|
||||
@sync.update(File.open(@config.file_gpg).read)
|
||||
@config.setLastUpdate()
|
||||
rescue Exception => e
|
||||
puts "#{I18n.t('cli.sync.error')}:\n#{e}"
|
||||
else
|
||||
@sync.close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Create a new config file
|
||||
|
|
58
lib/MPW.rb
58
lib/MPW.rb
|
@ -79,7 +79,7 @@ class MPW
|
|||
# @args: search -> the string to search
|
||||
# protocol -> the connection protocol (ssh, web, other)
|
||||
# @rtrn: a list with the resultat of the search
|
||||
def search(search, group=nil, protocol=nil)
|
||||
def search(search='', group=nil, protocol=nil)
|
||||
result = Array.new()
|
||||
|
||||
if !search.nil?
|
||||
|
@ -107,7 +107,7 @@ class MPW
|
|||
# @rtrn: a row with the resultat of the search
|
||||
def searchById(id)
|
||||
@data.each do |row|
|
||||
if @data[ID] == id
|
||||
if row[ID] == id
|
||||
return row
|
||||
end
|
||||
end
|
||||
|
@ -168,14 +168,15 @@ class MPW
|
|||
i = 0
|
||||
|
||||
@data.each do |row|
|
||||
if not row[ID] == id
|
||||
if row[ID] == id
|
||||
|
||||
if port.to_i <= 0
|
||||
port = nil
|
||||
end
|
||||
|
||||
row_update = Array.new()
|
||||
row[DATE] = Time.now.to_i
|
||||
row_update = Array.new()
|
||||
row_update[ID] = row[ID]
|
||||
row_update[DATE] = Time.now.to_i
|
||||
|
||||
name.nil? || name.empty? ? (row_update[NAME] = row[NAME]) : (row_update[NAME] = name)
|
||||
group.nil? || group.empty? ? (row_update[GROUP] = row[GROUP]) : (row_update[GROUP] = group)
|
||||
|
@ -205,7 +206,7 @@ class MPW
|
|||
i = 0
|
||||
@data.each do |row|
|
||||
if row[ID] == id
|
||||
@data.delete(i)
|
||||
@data.delete_at(i)
|
||||
return true
|
||||
end
|
||||
i += 1
|
||||
|
@ -286,6 +287,51 @@ class MPW
|
|||
end
|
||||
end
|
||||
|
||||
# Sync remote data and local data
|
||||
# @args: data_remote -> array with the data remote
|
||||
# last_update -> last update
|
||||
# @rtrn: false if data_remote is nil
|
||||
def sync(data_remote, last_update)
|
||||
if !data_remote.instance_of?(Array)
|
||||
return false
|
||||
end
|
||||
|
||||
@data.each do |l|
|
||||
j = 0
|
||||
update = false
|
||||
|
||||
# Update item
|
||||
data_remote.each do |r|
|
||||
if l[ID] == r[ID]
|
||||
if l[DATE].to_i < r[DATE].to_i
|
||||
self.update(l[ID], r[NAME], r[GROUP], r[SERVER], r[PROTOCOL], r[LOGIN], r[PASSWORD], r[PORT], r[COMMENT])
|
||||
end
|
||||
update = true
|
||||
data_remote.delete_at(j)
|
||||
break
|
||||
end
|
||||
j += 1
|
||||
end
|
||||
|
||||
# Delete an old item
|
||||
if !update && l[DATE].to_i < last_update
|
||||
self.remove(l[ID])
|
||||
end
|
||||
end
|
||||
|
||||
# Add item
|
||||
data_remote.each do |r|
|
||||
if r[DATE].to_i > last_update
|
||||
puts 'add'
|
||||
@data.push(r)
|
||||
end
|
||||
end
|
||||
|
||||
self.encrypt()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
# Generate a random password
|
||||
# @args: length -> the length password
|
||||
# @rtrn: a random string
|
||||
|
|
|
@ -15,11 +15,12 @@ class MPWConfig
|
|||
attr_accessor :lang
|
||||
attr_accessor :file_gpg
|
||||
attr_accessor :timeout_pwd
|
||||
attr_accessor :last_update
|
||||
attr_accessor :sync_host
|
||||
attr_accessor :sync_port
|
||||
attr_accessor :sync_pwd
|
||||
attr_accessor :sync_sufix
|
||||
attr_accessor :sync_last_update
|
||||
attr_accessor :sync_suffix
|
||||
attr_accessor :last_update
|
||||
|
||||
# Constructor
|
||||
# @args: file_config -> the specify config file
|
||||
|
@ -78,15 +79,15 @@ class MPWConfig
|
|||
def checkconfig()
|
||||
begin
|
||||
config = YAML::load_file(@file_config)
|
||||
@key = config['config']['key']
|
||||
@lang = config['config']['lang']
|
||||
@file_gpg = config['config']['file_gpg']
|
||||
@timeout_pwd = config['config']['timeout_pwd'].to_i
|
||||
@sync_host = config['config']['sync_host']
|
||||
@sync_port = config['config']['sync_port']
|
||||
@sync_pwd = config['config']['sync_pwd']
|
||||
@sync_sufix = config['config']['sync_suffix']
|
||||
@sync_last_update = config['config']['sync_last_update'].to_i
|
||||
@key = config['config']['key']
|
||||
@lang = config['config']['lang']
|
||||
@file_gpg = config['config']['file_gpg']
|
||||
@timeout_pwd = config['config']['timeout_pwd'].to_i
|
||||
@sync_host = config['config']['sync_host']
|
||||
@sync_port = config['config']['sync_port']
|
||||
@sync_pwd = config['config']['sync_pwd']
|
||||
@sync_sufix = config['config']['sync_suffix']
|
||||
@last_update = config['config']['last_update'].to_i
|
||||
|
||||
if @key.empty? || @file_gpg.empty?
|
||||
@error_msg = I18n.t('error.config.check')
|
||||
|
@ -102,5 +103,28 @@ class MPWConfig
|
|||
|
||||
return true
|
||||
end
|
||||
|
||||
def setLastUpdate()
|
||||
config = {'config' => {'key' => @key,
|
||||
'lang' => @lang,
|
||||
'file_gpg' => @file_gpg,
|
||||
'timeout_pwd' => @timeout_pwd,
|
||||
'sync_host' => @sync_host,
|
||||
'sync_port' => @sync_port,
|
||||
'sync_pwd' => @sync_pwd,
|
||||
'sync_suffix' => @sync_uffix,
|
||||
'last_update' => Time.now.to_i }}
|
||||
|
||||
begin
|
||||
File.open(@file_config, 'w') do |file|
|
||||
file << config.to_yaml
|
||||
end
|
||||
rescue Exception => e
|
||||
@error_msg = "#{I18n.t('error.config.write')}\n#{e}"
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -21,29 +21,33 @@ class Server
|
|||
server = TCPServer.open(@host, @port)
|
||||
loop do
|
||||
Thread.start(server.accept) do |client|
|
||||
msg = self.getClientMessage(client)
|
||||
while true do
|
||||
msg = self.getClientMessage(client)
|
||||
|
||||
if !msg
|
||||
next
|
||||
end
|
||||
|
||||
if msg['gpg_key'].nil? || msg['gpg_key'].empty? || msg['password'].nil? || msg['password'].empty?
|
||||
self.closeConnection(client)
|
||||
next
|
||||
end
|
||||
if !msg
|
||||
next
|
||||
end
|
||||
|
||||
if msg['gpg_key'].nil? || msg['gpg_key'].empty? || msg['password'].nil? || msg['password'].empty?
|
||||
self.closeConnection(client)
|
||||
next
|
||||
end
|
||||
|
||||
case msg['action']
|
||||
when 'get'
|
||||
client.puts self.getFile(msg)
|
||||
when 'update'
|
||||
client.puts self.updateFile(msg)
|
||||
when 'delete'
|
||||
client.puts self.deleteFile(msg)
|
||||
else
|
||||
client.puts 'Unknown command'
|
||||
case msg['action']
|
||||
when 'get'
|
||||
client.puts self.getFile(msg)
|
||||
when 'update'
|
||||
client.puts self.updateFile(msg)
|
||||
puts 'update'
|
||||
when 'delete'
|
||||
client.puts self.deleteFile(msg)
|
||||
when 'close'
|
||||
self.closeConnection(client)
|
||||
else
|
||||
client.puts 'Unknown command'
|
||||
self.closeConnection(client)
|
||||
end
|
||||
end
|
||||
|
||||
self.closeConnection(client)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -68,11 +72,11 @@ class Server
|
|||
last_update = gpg_data['gpg']['last_update']
|
||||
|
||||
if self.isAuthorized?(msg['password'], salt, hash)
|
||||
send_msg = {:action => 'get',
|
||||
:gpg_key => msg['gpg_key'],
|
||||
send_msg = {:action => 'get',
|
||||
:gpg_key => msg['gpg_key'],
|
||||
:last_update => last_update,
|
||||
:msg => 'done',
|
||||
:data => data}
|
||||
:msg => 'done',
|
||||
:data => data}
|
||||
else
|
||||
send_msg = {:action => 'get',
|
||||
:gpg_key => msg['gpg_key'],
|
||||
|
@ -80,10 +84,12 @@ class Server
|
|||
:error => 'not_authorized'}
|
||||
end
|
||||
else
|
||||
send_msg = {:action => 'get',
|
||||
:gpg_key => msg['gpg_key'],
|
||||
:msg => 'fail',
|
||||
:error => 'file_not_exist'}
|
||||
send_msg = {:action => 'get',
|
||||
:gpg_key => msg['gpg_key'],
|
||||
:last_update => 0,
|
||||
:data => '',
|
||||
:msg => 'fail',
|
||||
:error => 'file_not_exist'}
|
||||
end
|
||||
|
||||
return send_msg.to_json
|
||||
|
@ -129,7 +135,7 @@ class Server
|
|||
'last_update' => last_update,
|
||||
'data' => data}}
|
||||
|
||||
File.open(file_gpg, 'w') do |file|
|
||||
File.open(file_gpg, 'w+') do |file|
|
||||
file << config.to_yaml
|
||||
end
|
||||
|
||||
|
@ -242,11 +248,11 @@ class Server
|
|||
begin
|
||||
config = YAML::load_file(file_config)
|
||||
@host = config['config']['host']
|
||||
@port = config['config']['port']
|
||||
@port = config['config']['port'].to_i
|
||||
@data_dir = config['config']['data_dir']
|
||||
@timeout = config['config']['timeout'].to_i
|
||||
|
||||
if @host.empty? || @port.empty? || @data_dir.empty?
|
||||
if @host.empty? || @port <= 0 || @data_dir.empty?
|
||||
puts I18n.t('server.checkconfig.fail')
|
||||
puts I18n.t('server.checkconfig.empty')
|
||||
return false
|
||||
|
|
105
lib/Sync.rb
Normal file
105
lib/Sync.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/ruby
|
||||
# author: nishiki
|
||||
# mail: nishiki@yaegashi.fr
|
||||
# info: a simple script who manage your passwords
|
||||
|
||||
require 'rubygems'
|
||||
require 'i18n'
|
||||
require 'socket'
|
||||
require 'json'
|
||||
|
||||
require "#{APP_ROOT}/lib/MPW.rb"
|
||||
|
||||
class Sync
|
||||
|
||||
attr_accessor :error_msg
|
||||
|
||||
def initialize()
|
||||
@error_msg = nil
|
||||
end
|
||||
|
||||
def disable()
|
||||
@sync = false
|
||||
end
|
||||
|
||||
def connect(host, port, gpg_key, password, suffix=nil)
|
||||
@gpg_key = gpg_key
|
||||
@password = password
|
||||
@suffix = suffix
|
||||
|
||||
begin
|
||||
@socket= TCPSocket.new(host, port)
|
||||
@sync = true
|
||||
rescue Exception => e
|
||||
@error_msg = "ERROR: Connection impossible\n#{e}"
|
||||
@sync = false
|
||||
end
|
||||
|
||||
return @sync
|
||||
end
|
||||
|
||||
def get(gpg_password)
|
||||
send_msg = {:action => 'get',
|
||||
:gpg_key => @gpg_key,
|
||||
:password => @password,
|
||||
:suffix => @suffix}
|
||||
|
||||
@socket.puts send_msg.to_json
|
||||
msg = JSON.parse(@socket.gets)
|
||||
|
||||
case msg['error']
|
||||
when nil, 'file_not_exist'
|
||||
tmp_file = "/tmp/mpw-#{MPW.generatePassword()}.gpg"
|
||||
File.open(tmp_file, 'w') do |file|
|
||||
file << msg['data']
|
||||
end
|
||||
|
||||
@mpw = MPW.new(tmp_file)
|
||||
if !@mpw.decrypt(gpg_password)
|
||||
return nil
|
||||
end
|
||||
|
||||
File.unlink(tmp_file)
|
||||
|
||||
return @mpw.search()
|
||||
when 'not_authorized'
|
||||
@error_msg = 'not authorized'
|
||||
else
|
||||
@error_msg = 'error unknow'
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
def update(data)
|
||||
send_msg = {:action => 'update',
|
||||
:gpg_key => @gpg_key,
|
||||
:password => @password,
|
||||
:suffix => @suffix,
|
||||
:data => data}
|
||||
|
||||
@socket.puts send_msg.to_json
|
||||
msg = JSON.parse(@socket.gets)
|
||||
|
||||
case msg['error']
|
||||
when nil
|
||||
return true
|
||||
when 'not_authorized'
|
||||
@error_msg = 'not authorized'
|
||||
when 'no_data'
|
||||
@error_msg = 'no data'
|
||||
else
|
||||
@error_msg = 'error unknow'
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
def delete()
|
||||
end
|
||||
|
||||
def close()
|
||||
send_msg = {:action => 'close'}
|
||||
@socket.puts send_msg.to_json
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue