pwsafe-agent 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pwsafe-agent.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Fabrizio Regini
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # Pwsafe::Agent
2
+
3
+ This gem is a wrapper for pwsafe composed of two executables which aim
4
+ to reduce the typing of the master password.
5
+
6
+ ## How it works
7
+
8
+ A daemon is executed and a client interacts with it to save the master
9
+ passwowrd for a specified amount of time. At any later invocation, the
10
+ client asks the daemon for the master password.
11
+
12
+ Client and server communication is operated across a unix socket.
13
+
14
+ Master password is expired after 10 minutes.
15
+
16
+ Any printed output is saved to temporary file into `~/.pwsafe-agent/tmp` only for
17
+ the time required for the client program to execute. This is impossible to avoid
18
+ given the way pwsafe is designed. If you find any better solution, your contribution
19
+ is more than welcome.
20
+
21
+ Server pid is saved at `~/.pwsafe-agent/pid`
22
+
23
+ ## Usage
24
+
25
+ pwsafe-client [any-pwsafe-option]
26
+
27
+ Examples:
28
+
29
+ pwsafe-client --list heroku
30
+
31
+ You can avoid the saving of master password to the server, or flush the saved password
32
+ by passing `--flush` option to the client, even in conjunction with any pwsafe command:
33
+
34
+ pwsafe-client -up amazon --flush
35
+
36
+
37
+ ## Installation
38
+
39
+ gem install pwsafe-agent
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env ruby
2
+ require 'socket'
3
+ require 'pathname'
4
+ require 'logger'
5
+
6
+ AGENT_DIR = File.expand_path('~/.pwsafe-agent')
7
+ SOCKET_PATH = File.join(AGENT_DIR, 'socket')
8
+
9
+ PID_FILE = File.join(AGENT_DIR, 'pid')
10
+ LOG_FILE = File.join(AGENT_DIR, 'logs')
11
+
12
+ LOGGER = Logger.new(LOG_FILE)
13
+ PWSTORE = Hash.new
14
+
15
+ PWSTORE[:password] = Hash.new
16
+
17
+ STORE_TIME = 60 * 10 # minutes
18
+
19
+ if File.exists? PID_FILE
20
+ puts "Found pid at #{PID_FILE}, exiting"
21
+ exit 126
22
+ end
23
+
24
+ `mkdir -p #{AGENT_DIR}`
25
+ `rm #{SOCKET_PATH}`
26
+
27
+ Process.daemon(true)
28
+
29
+ def write_pid
30
+ `echo "#{Process.pid}" > #{PID_FILE}`
31
+ end
32
+
33
+ def clear_pid
34
+ `rm #{PID_FILE}`
35
+ end
36
+
37
+ Process.fork do
38
+ write_pid
39
+
40
+ Signal.trap('TERM') do
41
+ LOGGER.debug "Received TERM, exiting"
42
+ clear_pid && exit
43
+ end
44
+
45
+ begin
46
+ cleaner_thread = Thread.new do
47
+ loop do
48
+ begin
49
+ sleep 10
50
+ if PWSTORE[:password][:time] && PWSTORE[:password][:time] < Time.now - STORE_TIME
51
+ PWSTORE[:password] = Hash.new
52
+ end
53
+ rescue => e
54
+ LOGGER.error "#{e.message}"
55
+ end
56
+ end
57
+ end
58
+
59
+ UNIXServer.open(SOCKET_PATH) do |server|
60
+ while true do
61
+ accepted = server.accept # this block
62
+ command = accepted.read
63
+ begin
64
+ if command =~ /SET=(.+)/
65
+ PWSTORE[:password] = {:time => Time.now, :password => $1}
66
+ accepted.write PWSTORE[:password][:password]
67
+ elsif command == 'GET'
68
+ accepted.write PWSTORE[:password][:password]
69
+ elsif command == "FLUSH"
70
+ PWSTORE[:password] = Hash.new
71
+ else
72
+ accepted.write "-"
73
+ end
74
+
75
+ accepted.close
76
+ rescue => e
77
+ LOGGER.error "#{e.message} #{e.backtrace.join}"
78
+ end
79
+ end
80
+ end
81
+ rescue => e
82
+ LOGGER.error "#{e.message} #{e.backtrace.join}"
83
+ end
84
+ clear_pid
85
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This should wrap pwsafe
3
+ #
4
+ require File.expand_path('../lib/pwsafe-agent/client', File.dirname(__FILE__))
5
+
6
+ Pwsafe::Agent::Client.new(ARGV).run
@@ -0,0 +1,6 @@
1
+ require "pwsafe-agent/version"
2
+
3
+ module Pwsafe
4
+ module Agent
5
+ end
6
+ end
@@ -0,0 +1,62 @@
1
+ require 'socket'
2
+ require 'pathname'
3
+ require 'logger'
4
+
5
+ require File.expand_path('driver', File.dirname(__FILE__))
6
+
7
+ module Pwsafe
8
+ module Agent
9
+
10
+ BASE_DIR = '~/.pwsafe-agent'
11
+ SOCKET_PATH = File.expand_path(File.join(BASE_DIR, 'socket'))
12
+ TMP_FILE_PATH = File.expand_path(File.join(BASE_DIR, 'tmp'))
13
+ PWSAFE = ENV['PWSAFE_COMMAND'] || 'pwsafe'
14
+
15
+ class Client
16
+ def initialize(args)
17
+ system 'pwsafe-agent'
18
+ @args = args
19
+ end
20
+
21
+ def driver
22
+ @driver ||= Driver.new
23
+ end
24
+
25
+ def print_temp_file
26
+ puts File.read(TMP_FILE_PATH)
27
+ end
28
+
29
+ def remove_temp_file
30
+ system "rm #{TMP_FILE_PATH}"
31
+ end
32
+
33
+ def command
34
+ password = driver.get
35
+ "echo '#{password}' | #{PWSAFE} -E --output=#{TMP_FILE_PATH} #{stringified_args} > /dev/null"
36
+ end
37
+
38
+ def pwsafe_run
39
+ if system(command)
40
+ print_temp_file
41
+ remove_temp_file
42
+ else
43
+ puts "Some error occurred during command"
44
+ driver.flush
45
+ end
46
+ end
47
+
48
+ def run
49
+ if @args.delete('--flush')
50
+ driver.flush
51
+ end
52
+
53
+ pwsafe_run
54
+ end
55
+
56
+ def stringified_args
57
+ @args.join ' '
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,50 @@
1
+ module Pwsafe
2
+ module Agent
3
+ class Driver
4
+ def initialize
5
+ @password = nil
6
+ end
7
+
8
+ def set
9
+ UNIXSocket.open(SOCKET_PATH) do |sock|
10
+ puts "type password"
11
+ begin
12
+ system 'stty -echo'
13
+ password = STDIN.gets.chomp
14
+ ensure
15
+ system 'stty echo'
16
+ end
17
+ sock.write "SET=#{password}"
18
+ sock.close_write
19
+
20
+ @password = sock.read
21
+ sock.close
22
+ end
23
+ end
24
+
25
+ def flush
26
+ UNIXSocket.open(SOCKET_PATH) do |sock|
27
+ sock.write "FLUSH"
28
+ sock.close
29
+ end
30
+ end
31
+
32
+ def blank_password?
33
+ @password == ''
34
+ end
35
+
36
+ def get
37
+ UNIXSocket.open(SOCKET_PATH) do |sock|
38
+ sock.write 'GET'
39
+ sock.close_write
40
+
41
+ @password = sock.read
42
+ sock.close
43
+ end
44
+
45
+ set if blank_password?
46
+ @password
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ module Pwsafe
2
+ module Agent
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/pwsafe-agent/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Fabrizio Regini"]
6
+ gem.email = ["freegenie@gmail.com"]
7
+ gem.description = %q{Avoid master password typing in pwsafe}
8
+ gem.summary = <<-EOH
9
+ Make pwsafe on the command line more friendly
10
+ by avoiding the need of repetitive master password typing.
11
+ EOH
12
+
13
+ gem.homepage = "https://github.com/freegenie/pwsafe-agent"
14
+
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.name = "pwsafe-agent"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = Pwsafe::Agent::VERSION
21
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pwsafe-agent
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Fabrizio Regini
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-30 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Avoid master password typing in pwsafe
15
+ email:
16
+ - freegenie@gmail.com
17
+ executables:
18
+ - pwsafe-agent
19
+ - pwsafe-client
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - .gitignore
24
+ - Gemfile
25
+ - LICENSE
26
+ - README.md
27
+ - Rakefile
28
+ - bin/pwsafe-agent
29
+ - bin/pwsafe-client
30
+ - lib/pwsafe-agent.rb
31
+ - lib/pwsafe-agent/client.rb
32
+ - lib/pwsafe-agent/driver.rb
33
+ - lib/pwsafe-agent/version.rb
34
+ - pwsafe-agent.gemspec
35
+ homepage: https://github.com/freegenie/pwsafe-agent
36
+ licenses: []
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 1.8.24
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: Make pwsafe on the command line more friendly by avoiding the need of repetitive
59
+ master password typing.
60
+ test_files: []