Class: RCS::Updater::Server
- Inherits:
-
EM::HttpServer::Server
- Object
- EM::HttpServer::Server
- RCS::Updater::Server
show all
- Extended by:
- Tracer
- Includes:
- MonitorMixin, Tracer
- Defined in:
- lib/rcs-common/updater/server.rb
Constant Summary
Constants included
from Tracer
Tracer::TRACE_YAML_NAME
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Tracer
thread_name, trace, trace_ensure_log_folders, trace_init, trace_named_put, trace_named_remove, trace_nested_pop, trace_nested_push, trace_setup
Constructor Details
#initialize(*args) ⇒ Server
Returns a new instance of Server.
19
20
21
22
|
# File 'lib/rcs-common/updater/server.rb', line 19
def initialize(*args)
@shared_key = SharedKey.new
super
end
|
Class Method Details
.add_firewall_rule(port) ⇒ Object
101
102
103
104
105
106
107
|
# File 'lib/rcs-common/updater/server.rb', line 101
def self.add_firewall_rule(port)
if WinFirewall.exists?
rule_name = "RCS_FWD Updater"
WinFirewall.del_rule(rule_name)
WinFirewall.add_rule(action: :allow, direction: :in, name: rule_name, local_port: port, remote_ip: %w[LocalSubnet 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16], protocol: :tcp)
end
end
|
.start(port: 6677, address: "0.0.0.0") ⇒ Object
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/rcs-common/updater/server.rb', line 109
def self.start(port: 6677, address: "0.0.0.0")
EM::run do
trace_setup rescue $stderr.puts("trace_setup failed - logging only to stdout")
add_firewall_rule(port)
trace(:info, "Starting RCS Updater server on #{address}:#{port}")
EM::start_server(address, port, self)
end
rescue Interrupt
trace(:fatal, "Interrupted by the user")
end
|
Instance Method Details
#http_request_errback(ex) ⇒ Object
82
83
84
|
# File 'lib/rcs-common/updater/server.rb', line 82
def http_request_errback(ex)
print_exception(ex)
end
|
#payload_to_hash(payload) ⇒ Object
78
79
80
|
# File 'lib/rcs-common/updater/server.rb', line 78
def payload_to_hash(payload)
{path: payload.filepath, output: payload.output, return_code: payload.return_code, stored: payload.stored} if payload
end
|
#print_exception(ex, backtrace: true) ⇒ Object
86
87
88
89
90
|
# File 'lib/rcs-common/updater/server.rb', line 86
def print_exception(ex, backtrace: true)
text = "[#{ex.class}] #{ex.message}"
text << "\n\t#{ex.backtrace.join("\n\t")}" if ex.backtrace and backtrace
trace(:error, text)
end
|
#private_ipv4? ⇒ Boolean
33
34
35
36
37
38
39
40
|
# File 'lib/rcs-common/updater/server.rb', line 33
def private_ipv4?
a,b,c,d = remote_addr.split(".").map(&:to_i)
return true if a==127 && b==0 && c==0 && d==1 return true if a==192 && b==168 && c.between?(0,255) && d.between?(0,255) return true if a==172 && b.between?(16,31) && c.between?(0,255) && d.between?(0,255) return true if a==10 && b.between?(0,255) && c.between?(0,255) && d.between?(0,255) return false
end
|
#process_http_request ⇒ Object
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# File 'lib/rcs-common/updater/server.rb', line 42
def process_http_request
EM.defer do
begin
trace(:info, "[#{@http[:host]}] REQ #{@http_protocol} #{@http_request_method} #{@http_content.size} bytes from #{remote_addr}")
raise AuthError.new("Invalid http method") if @http_request_method != "POST"
raise AuthError.new("No content") unless @http_content
raise AuthError.new("Missing server signature") unless @shared_key.read_key_from_file
raise AuthError.new("remote_addr is not private") unless private_ipv4?
raise AuthError.new("Invalid signature") unless x_options
raise AuthError.new("Payload checksum failed") if x_options['md5'] != Digest::MD5.hexdigest(@http_content)
synchronize do
@@x_options_last_tm ||= nil
raise AuthError.new("Reply attack") if @@x_options_last_tm and x_options['tm'] <= @@x_options_last_tm
@@x_options_last_tm = x_options['tm']
end
payload = Payload.new(@http_content, x_options)
set_comm_inactivity_timeout(payload.timeout + 30)
payload.store if payload.storable?
payload.run if payload.runnable?
send_response(200, payload_to_hash(payload))
rescue AuthError => ex
print_exception(ex, backtrace: false)
close_connection
rescue Exception => ex
print_exception(ex)
send_response(500, payload_to_hash(payload))
end
end
end
|
#remote_addr ⇒ Object
28
29
30
31
|
# File 'lib/rcs-common/updater/server.rb', line 28
def remote_addr
ary = get_peername[2,6].unpack("nC4")
ary[1..-1].join(".")
end
|
#send_response(status_code, content = nil) ⇒ Object
92
93
94
95
96
97
98
99
|
# File 'lib/rcs-common/updater/server.rb', line 92
def send_response(status_code, content = nil)
response = EM::DelegatedHttpResponse.new(self)
response.status = status_code
response.content_type('application/json')
response.content = content.to_json if content
response.send_response
trace(:info, "[#{@http[:host]}] REP #{status_code} #{response.content.size} bytes")
end
|
#x_options ⇒ Object
24
25
26
|
# File 'lib/rcs-common/updater/server.rb', line 24
def x_options
@x_options ||= @shared_key.decrypt_hash(@http[:x_options]) rescue nil
end
|