1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
77
78
79
80
81
82
83
84
85
86
|
require 'puppet/network/authorization'
require 'xmlrpc/server'
# Just silly.
class ::XMLRPC::FaultException
def to_s
self.message
end
end
module Puppet::Network
# Most of our subclassing is just so that we can get
# access to information from the request object, like
# the client name and IP address.
module XMLRPCProcessor
include Puppet::Network::Authorization
ERR_UNAUTHORIZED = 30
def add_handler(interface, handler)
@loadedhandlers << interface.prefix
super(interface, handler)
end
def handler_loaded?(handler)
@loadedhandlers.include?(handler.to_s)
end
# Convert our data and client request into xmlrpc calls, and verify
# they're authorized and such-like. This method differs from the
# default in that it expects a ClientRequest object in addition to the
# data.
def process(data, request)
call, params = parser().parseMethodCall(data)
params << request.name << request.ip
handler, method = call.split(".")
request.handler = handler
request.method = method
begin
verify(request)
rescue InvalidClientRequest => detail
raise ::XMLRPC::FaultException.new(ERR_UNAUTHORIZED, detail.to_s)
end
handle(request.call, *params)
end
private
# Provide error handling for method calls.
def protect_service(obj, *args)
begin
obj.call(*args)
rescue ::XMLRPC::FaultException
raise
rescue Puppet::AuthorizationError => detail
Puppet.err "Permission denied: #{detail}"
raise ::XMLRPC::FaultException.new(
1, detail.to_s
)
rescue Puppet::Error => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err detail.to_s
error = ::XMLRPC::FaultException.new(
1, detail.to_s
)
error.set_backtrace detail.backtrace
raise error
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not call: #{detail}"
error = ::XMLRPC::FaultException.new(1, detail.to_s)
error.set_backtrace detail.backtrace
raise error
end
end
# Set up our service hook and init our handler list.
def setup_processor
@loadedhandlers = []
self.set_service_hook do |obj, *args|
protect_service(obj, *args)
end
end
end
end
|