pwsafe-agent 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []