1
0
Fork 0
mirror of https://github.com/nishiki/manage-password.git synced 2025-02-20 01:50:04 +00:00

first sync work :)

This commit is contained in:
nishiki 2014-01-14 23:00:52 +01:00
parent bc276f23c1
commit 8b86040af0
5 changed files with 248 additions and 48 deletions

View file

@ -8,9 +8,11 @@ require 'highline/import'
require 'pathname' require 'pathname'
require 'readline' require 'readline'
require 'i18n' require 'i18n'
require 'yaml'
require "#{APP_ROOT}/lib/MPW.rb" require "#{APP_ROOT}/lib/MPW.rb"
require "#{APP_ROOT}/lib/MPWConfig.rb" require "#{APP_ROOT}/lib/MPWConfig.rb"
require "#{APP_ROOT}/lib/Sync.rb"
class Cli class Cli
@ -29,6 +31,23 @@ class Cli
puts "#{I18n.t('cli.display.error')}: #{@mpw.error_msg}" puts "#{I18n.t('cli.display.error')}: #{@mpw.error_msg}"
exit 2 exit 2
end 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 end
# Create a new config file # Create a new config file

View file

@ -79,7 +79,7 @@ class MPW
# @args: search -> the string to search # @args: search -> the string to search
# protocol -> the connection protocol (ssh, web, other) # protocol -> the connection protocol (ssh, web, other)
# @rtrn: a list with the resultat of the search # @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() result = Array.new()
if !search.nil? if !search.nil?
@ -107,7 +107,7 @@ class MPW
# @rtrn: a row with the resultat of the search # @rtrn: a row with the resultat of the search
def searchById(id) def searchById(id)
@data.each do |row| @data.each do |row|
if @data[ID] == id if row[ID] == id
return row return row
end end
end end
@ -168,14 +168,15 @@ class MPW
i = 0 i = 0
@data.each do |row| @data.each do |row|
if not row[ID] == id if row[ID] == id
if port.to_i <= 0 if port.to_i <= 0
port = nil port = nil
end end
row_update = Array.new() row_update = Array.new()
row[DATE] = Time.now.to_i 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) 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) group.nil? || group.empty? ? (row_update[GROUP] = row[GROUP]) : (row_update[GROUP] = group)
@ -205,7 +206,7 @@ class MPW
i = 0 i = 0
@data.each do |row| @data.each do |row|
if row[ID] == id if row[ID] == id
@data.delete(i) @data.delete_at(i)
return true return true
end end
i += 1 i += 1
@ -286,6 +287,51 @@ class MPW
end end
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 # Generate a random password
# @args: length -> the length password # @args: length -> the length password
# @rtrn: a random string # @rtrn: a random string

View file

@ -15,11 +15,12 @@ class MPWConfig
attr_accessor :lang attr_accessor :lang
attr_accessor :file_gpg attr_accessor :file_gpg
attr_accessor :timeout_pwd attr_accessor :timeout_pwd
attr_accessor :last_update
attr_accessor :sync_host attr_accessor :sync_host
attr_accessor :sync_port attr_accessor :sync_port
attr_accessor :sync_pwd attr_accessor :sync_pwd
attr_accessor :sync_sufix attr_accessor :sync_suffix
attr_accessor :sync_last_update attr_accessor :last_update
# Constructor # Constructor
# @args: file_config -> the specify config file # @args: file_config -> the specify config file
@ -78,15 +79,15 @@ class MPWConfig
def checkconfig() def checkconfig()
begin begin
config = YAML::load_file(@file_config) config = YAML::load_file(@file_config)
@key = config['config']['key'] @key = config['config']['key']
@lang = config['config']['lang'] @lang = config['config']['lang']
@file_gpg = config['config']['file_gpg'] @file_gpg = config['config']['file_gpg']
@timeout_pwd = config['config']['timeout_pwd'].to_i @timeout_pwd = config['config']['timeout_pwd'].to_i
@sync_host = config['config']['sync_host'] @sync_host = config['config']['sync_host']
@sync_port = config['config']['sync_port'] @sync_port = config['config']['sync_port']
@sync_pwd = config['config']['sync_pwd'] @sync_pwd = config['config']['sync_pwd']
@sync_sufix = config['config']['sync_suffix'] @sync_sufix = config['config']['sync_suffix']
@sync_last_update = config['config']['sync_last_update'].to_i @last_update = config['config']['last_update'].to_i
if @key.empty? || @file_gpg.empty? if @key.empty? || @file_gpg.empty?
@error_msg = I18n.t('error.config.check') @error_msg = I18n.t('error.config.check')
@ -102,5 +103,28 @@ class MPWConfig
return true return true
end 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 end

View file

@ -21,29 +21,33 @@ class Server
server = TCPServer.open(@host, @port) server = TCPServer.open(@host, @port)
loop do loop do
Thread.start(server.accept) do |client| Thread.start(server.accept) do |client|
msg = self.getClientMessage(client) while true do
msg = self.getClientMessage(client)
if !msg if !msg
next next
end end
if msg['gpg_key'].nil? || msg['gpg_key'].empty? || msg['password'].nil? || msg['password'].empty? if msg['gpg_key'].nil? || msg['gpg_key'].empty? || msg['password'].nil? || msg['password'].empty?
self.closeConnection(client) self.closeConnection(client)
next next
end end
case msg['action'] case msg['action']
when 'get' when 'get'
client.puts self.getFile(msg) client.puts self.getFile(msg)
when 'update' when 'update'
client.puts self.updateFile(msg) client.puts self.updateFile(msg)
when 'delete' puts 'update'
client.puts self.deleteFile(msg) when 'delete'
else client.puts self.deleteFile(msg)
client.puts 'Unknown command' when 'close'
self.closeConnection(client)
else
client.puts 'Unknown command'
self.closeConnection(client)
end
end end
self.closeConnection(client)
end end
end end
end end
@ -68,11 +72,11 @@ class Server
last_update = gpg_data['gpg']['last_update'] last_update = gpg_data['gpg']['last_update']
if self.isAuthorized?(msg['password'], salt, hash) if self.isAuthorized?(msg['password'], salt, hash)
send_msg = {:action => 'get', send_msg = {:action => 'get',
:gpg_key => msg['gpg_key'], :gpg_key => msg['gpg_key'],
:last_update => last_update, :last_update => last_update,
:msg => 'done', :msg => 'done',
:data => data} :data => data}
else else
send_msg = {:action => 'get', send_msg = {:action => 'get',
:gpg_key => msg['gpg_key'], :gpg_key => msg['gpg_key'],
@ -80,10 +84,12 @@ class Server
:error => 'not_authorized'} :error => 'not_authorized'}
end end
else else
send_msg = {:action => 'get', send_msg = {:action => 'get',
:gpg_key => msg['gpg_key'], :gpg_key => msg['gpg_key'],
:msg => 'fail', :last_update => 0,
:error => 'file_not_exist'} :data => '',
:msg => 'fail',
:error => 'file_not_exist'}
end end
return send_msg.to_json return send_msg.to_json
@ -129,7 +135,7 @@ class Server
'last_update' => last_update, 'last_update' => last_update,
'data' => data}} 'data' => data}}
File.open(file_gpg, 'w') do |file| File.open(file_gpg, 'w+') do |file|
file << config.to_yaml file << config.to_yaml
end end
@ -242,11 +248,11 @@ class Server
begin begin
config = YAML::load_file(file_config) config = YAML::load_file(file_config)
@host = config['config']['host'] @host = config['config']['host']
@port = config['config']['port'] @port = config['config']['port'].to_i
@data_dir = config['config']['data_dir'] @data_dir = config['config']['data_dir']
@timeout = config['config']['timeout'].to_i @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.fail')
puts I18n.t('server.checkconfig.empty') puts I18n.t('server.checkconfig.empty')
return false return false

105
lib/Sync.rb Normal file
View 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