tem_multi_proxy 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|