tem_multi_proxy 0.1
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.
- data/CHANGELOG +1 -0
- data/LICENSE +21 -0
- data/Manifest +8 -0
- data/README +9 -0
- data/Rakefile +26 -0
- data/bin/tem_multi_proxy +7 -0
- data/lib/tem_multi_proxy.rb +12 -0
- data/lib/tem_multi_proxy/manager.rb +132 -0
- data/tem_multi_proxy.gemspec +44 -0
- metadata +112 -0
data/CHANGELOG
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
v0.1. Initial release. Standalone manager works.
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009 Massachusetts Institute of Technology
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Manifest
ADDED
data/README
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
tem_multi_proxy is a tool that automatically creates a TEM proxy for each PC/SC
|
2
|
+
reader on the system. The tool reacts appropriately to PC/SC events like
|
3
|
+
readers being added or cards being inserted. It also re-spawns proxy processes
|
4
|
+
if they die.
|
5
|
+
|
6
|
+
The utility's intended use is for TEM clusters (systems with multiple TEMs
|
7
|
+
attached), where the TEM's auto-configuration mechanism wouldn't allow access to
|
8
|
+
all the TEMs.
|
9
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'echoe'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('tem_multi_proxy') do |p|
|
6
|
+
p.project = 'tem' # rubyforge project
|
7
|
+
p.docs_host = "costan@rubyforge.org:/var/www/gforge-projects/tem/rdoc/"
|
8
|
+
|
9
|
+
p.author = 'Victor Costan'
|
10
|
+
p.email = 'victor@costan.us'
|
11
|
+
p.summary = 'Maintains TEM proxies for all the physically attached TEMs.'
|
12
|
+
p.url = 'http://tem.rubyforge.org'
|
13
|
+
p.dependencies = ['rbtree >=0.2.1',
|
14
|
+
'smartcard >=0.3.1',
|
15
|
+
'tem_ruby >=0.11',
|
16
|
+
'zerg_support >=0.0.9']
|
17
|
+
|
18
|
+
p.need_tar_gz = !Platform.windows?
|
19
|
+
p.need_zip = !Platform.windows?
|
20
|
+
p.rdoc_pattern = /^(lib|bin|tasks|ext)|^BUILD|^README|^CHANGELOG|^TODO|^LICENSE|^COPYING$/
|
21
|
+
end
|
22
|
+
|
23
|
+
if $0 == __FILE__
|
24
|
+
Rake.application = Rake::Application.new
|
25
|
+
Rake.application.run
|
26
|
+
end
|
data/bin/tem_multi_proxy
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'rbtree'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
|
6
|
+
# :nodoc: namespace
|
7
|
+
module Tem::MultiProxy
|
8
|
+
|
9
|
+
class Manager
|
10
|
+
def initialize
|
11
|
+
@pcsc_context = Smartcard::PCSC::Context.new(Smartcard::PCSC::SCOPE_SYSTEM)
|
12
|
+
@proxy_pids = {}
|
13
|
+
@proxy_ports = {}
|
14
|
+
@free_ports = RBTree.new
|
15
|
+
(9001...9050).each { |port| @free_ports[port] = true }
|
16
|
+
@logger = Logger.new STDERR
|
17
|
+
end
|
18
|
+
|
19
|
+
# Polls each smartcard reader to see if there's a card present.
|
20
|
+
def poll_readers
|
21
|
+
readers = @pcsc_context.list_readers(nil).map { |name| { :name => name }}
|
22
|
+
reader_states = Smartcard::PCSC::ReaderStates.new readers.length
|
23
|
+
readers.each_with_index do |reader, i|
|
24
|
+
reader_states.set_reader_name_of!(i, reader[:name])
|
25
|
+
reader_states.set_current_state_of!(i, Smartcard::PCSC::STATE_UNAWARE)
|
26
|
+
end
|
27
|
+
@pcsc_context.get_status_change reader_states, 100
|
28
|
+
|
29
|
+
readers.each_with_index do |reader, i|
|
30
|
+
reader[:atr] = reader_states.atr_of i
|
31
|
+
# current_state_of is buggy on pcsclite, using the ATR for card detection.
|
32
|
+
if reader[:atr].length == 0
|
33
|
+
reader[:card] = false
|
34
|
+
reader[:atr] = nil
|
35
|
+
else
|
36
|
+
reader[:card] = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
readers
|
41
|
+
end
|
42
|
+
|
43
|
+
# Allocates a port for a TEM proxy.
|
44
|
+
def alloc_proxy_port(reader_name)
|
45
|
+
port = @free_ports.min.first
|
46
|
+
@free_ports.delete port
|
47
|
+
@proxy_ports[reader_name] = port
|
48
|
+
port
|
49
|
+
end
|
50
|
+
|
51
|
+
# Marks a TEM proxy port as free.
|
52
|
+
def free_proxy_port(reader_name)
|
53
|
+
port = @proxy_ports[reader_name]
|
54
|
+
return unless port
|
55
|
+
@proxy_ports.delete reader_name
|
56
|
+
@free_ports[port] = true
|
57
|
+
end
|
58
|
+
|
59
|
+
# Launches a tem_proxy process connecting to a reader.
|
60
|
+
def spawn_proxy_for_reader(reader)
|
61
|
+
proxy_port = alloc_proxy_port reader[:name]
|
62
|
+
proxy_pid = Zerg::Support::Process.spawn 'tem_proxy', [proxy_port.to_s],
|
63
|
+
:env => {'TEM_PORT' => reader[:name], 'DEBUG' => 'no'},
|
64
|
+
:pgroup => true
|
65
|
+
@proxy_pids[reader[:name]] = proxy_pid
|
66
|
+
end
|
67
|
+
|
68
|
+
# Updates the internal status to reflect that a tem_proxy process died.
|
69
|
+
def proxy_died(reader_name)
|
70
|
+
free_proxy_port reader_name
|
71
|
+
@proxy_pids.delete reader_name
|
72
|
+
end
|
73
|
+
|
74
|
+
# Kills the tem_proxy process for a reader.
|
75
|
+
def kill_proxy(reader_name)
|
76
|
+
if proxy_pid = @proxy_pids[reader_name]
|
77
|
+
Zerg::Support::Process.kill_tree proxy_pid
|
78
|
+
end
|
79
|
+
proxy_died reader_name
|
80
|
+
end
|
81
|
+
|
82
|
+
# Kills all the proxy processes.
|
83
|
+
def kill_all_proxies
|
84
|
+
processes = Zerg::Support::Process.processes
|
85
|
+
processes.each do |proc_info|
|
86
|
+
next unless /tem_proxy/ =~ proc_info[:command_line]
|
87
|
+
@logger.info "Mass-killing TEM proxy (pid #{proc_info[:pid]})"
|
88
|
+
Zerg::Support::Process::kill_tree proc_info[:pid]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Synchronizes the running tem_proxy processes with the list of readers.
|
93
|
+
def sync_reader_proxies
|
94
|
+
processes = Zerg::Support::Process.processes_by_id
|
95
|
+
# Check for crashed tem_proxy processes.
|
96
|
+
@proxy_pids.each do |reader_name, pid|
|
97
|
+
proc_info = processes[pid]
|
98
|
+
unless proc_info and /tem_proxy/ =~ proc_info[:command_line]
|
99
|
+
@logger.warn "TEM proxy for #{reader_name} (pid #{pid}) died."
|
100
|
+
proxy_died reader_name
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
live_readers = poll_readers.select { |reader| reader[:card] }
|
105
|
+
# Kill proxies whose readers aren't available.
|
106
|
+
live_reader_names = Set.new live_readers.map { |reader| reader[:name] }
|
107
|
+
@proxy_pids.keys.each do |reader_name|
|
108
|
+
next if live_reader_names.include? reader_name
|
109
|
+
@logger.info "Killing TEM proxy for #{reader_name}. " +
|
110
|
+
"(pid #{@proxy_pids[reader_name]})"
|
111
|
+
kill_proxy reader_name
|
112
|
+
end
|
113
|
+
|
114
|
+
# Spawn proxies for readers without them.
|
115
|
+
live_readers.each do |reader|
|
116
|
+
next if @proxy_pids[reader[:name]]
|
117
|
+
@logger.info "Spawning new TEM proxy for #{reader[:name]}."
|
118
|
+
spawn_proxy_for_reader reader
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Never-ending loop mananging TEM proxies for all the readers.
|
123
|
+
def management_loop
|
124
|
+
kill_all_proxies
|
125
|
+
loop do
|
126
|
+
sync_reader_proxies
|
127
|
+
Kernel.sleep 1
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end # namespace Tem::MultiProxy
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{tem_multi_proxy}
|
5
|
+
s.version = "0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Victor Costan"]
|
9
|
+
s.date = %q{2009-06-01}
|
10
|
+
s.default_executable = %q{tem_multi_proxy}
|
11
|
+
s.description = %q{Maintains TEM proxies for all the physically attached TEMs.}
|
12
|
+
s.email = %q{victor@costan.us}
|
13
|
+
s.executables = ["tem_multi_proxy"]
|
14
|
+
s.extra_rdoc_files = ["bin/tem_multi_proxy", "CHANGELOG", "lib/tem_multi_proxy/manager.rb", "lib/tem_multi_proxy.rb", "LICENSE", "README"]
|
15
|
+
s.files = ["bin/tem_multi_proxy", "CHANGELOG", "lib/tem_multi_proxy/manager.rb", "lib/tem_multi_proxy.rb", "LICENSE", "Rakefile", "README", "Manifest", "tem_multi_proxy.gemspec"]
|
16
|
+
s.homepage = %q{http://tem.rubyforge.org}
|
17
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Tem_multi_proxy", "--main", "README"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubyforge_project = %q{tem}
|
20
|
+
s.rubygems_version = %q{1.3.4}
|
21
|
+
s.summary = %q{Maintains TEM proxies for all the physically attached TEMs.}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 3
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
s.add_runtime_dependency(%q<rbtree>, [">= 0.2.1"])
|
29
|
+
s.add_runtime_dependency(%q<smartcard>, [">= 0.3.1"])
|
30
|
+
s.add_runtime_dependency(%q<tem_ruby>, [">= 0.11"])
|
31
|
+
s.add_runtime_dependency(%q<zerg_support>, [">= 0.0.9"])
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<rbtree>, [">= 0.2.1"])
|
34
|
+
s.add_dependency(%q<smartcard>, [">= 0.3.1"])
|
35
|
+
s.add_dependency(%q<tem_ruby>, [">= 0.11"])
|
36
|
+
s.add_dependency(%q<zerg_support>, [">= 0.0.9"])
|
37
|
+
end
|
38
|
+
else
|
39
|
+
s.add_dependency(%q<rbtree>, [">= 0.2.1"])
|
40
|
+
s.add_dependency(%q<smartcard>, [">= 0.3.1"])
|
41
|
+
s.add_dependency(%q<tem_ruby>, [">= 0.11"])
|
42
|
+
s.add_dependency(%q<zerg_support>, [">= 0.0.9"])
|
43
|
+
end
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tem_multi_proxy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Victor Costan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-01 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rbtree
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.2.1
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: smartcard
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.1
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: tem_ruby
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0.11"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: zerg_support
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.0.9
|
54
|
+
version:
|
55
|
+
description: Maintains TEM proxies for all the physically attached TEMs.
|
56
|
+
email: victor@costan.us
|
57
|
+
executables:
|
58
|
+
- tem_multi_proxy
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- bin/tem_multi_proxy
|
63
|
+
- CHANGELOG
|
64
|
+
- lib/tem_multi_proxy/manager.rb
|
65
|
+
- lib/tem_multi_proxy.rb
|
66
|
+
- LICENSE
|
67
|
+
- README
|
68
|
+
files:
|
69
|
+
- bin/tem_multi_proxy
|
70
|
+
- CHANGELOG
|
71
|
+
- lib/tem_multi_proxy/manager.rb
|
72
|
+
- lib/tem_multi_proxy.rb
|
73
|
+
- LICENSE
|
74
|
+
- Rakefile
|
75
|
+
- README
|
76
|
+
- Manifest
|
77
|
+
- tem_multi_proxy.gemspec
|
78
|
+
has_rdoc: true
|
79
|
+
homepage: http://tem.rubyforge.org
|
80
|
+
licenses: []
|
81
|
+
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options:
|
84
|
+
- --line-numbers
|
85
|
+
- --inline-source
|
86
|
+
- --title
|
87
|
+
- Tem_multi_proxy
|
88
|
+
- --main
|
89
|
+
- README
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
97
|
+
version:
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: "1.2"
|
103
|
+
version:
|
104
|
+
requirements: []
|
105
|
+
|
106
|
+
rubyforge_project: tem
|
107
|
+
rubygems_version: 1.3.4
|
108
|
+
signing_key:
|
109
|
+
specification_version: 3
|
110
|
+
summary: Maintains TEM proxies for all the physically attached TEMs.
|
111
|
+
test_files: []
|
112
|
+
|