drbservice 1.0.4
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.tar.gz.sig +2 -0
- data/.gemtest +0 -0
- data/ChangeLog +249 -0
- data/History.rdoc +4 -0
- data/LICENSE +27 -0
- data/Manifest.txt +18 -0
- data/README.rdoc +74 -0
- data/Rakefile +38 -0
- data/examples/homedirservice.rb +110 -0
- data/examples/rubyversion.rb +26 -0
- data/lib/drb/authsslprotocol.rb +55 -0
- data/lib/drbservice.rb +208 -0
- data/lib/drbservice/ldapauth.rb +200 -0
- data/lib/drbservice/passwordauth.rb +58 -0
- data/lib/drbservice/utils.rb +426 -0
- data/spec/drb/authsslprotocol_spec.rb +76 -0
- data/spec/drbservice/ldapauth_spec.rb +382 -0
- data/spec/drbservice/passwordauth_spec.rb +141 -0
- data/spec/drbservice_spec.rb +168 -0
- data/spec/lib/helpers.rb +108 -0
- metadata +166 -0
- metadata.gz.sig +2 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'digest/sha2'
|
5
|
+
require 'drbservice'
|
6
|
+
|
7
|
+
# An authentication strategy for DRbService -- set a password via a
|
8
|
+
# class method.
|
9
|
+
module DRbService::PasswordAuthentication
|
10
|
+
|
11
|
+
### Methods added to including classes when PasswordAuthentication is
|
12
|
+
### mixed in.
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
# The SHA2 digest of the service password
|
16
|
+
attr_accessor :password_digest
|
17
|
+
|
18
|
+
### Set a password for the service. If you don't specify a password, even guarded
|
19
|
+
### methods can be accessed. With a password set, the remote side can still call
|
20
|
+
### unguarded methods, but all other methods will be hidden.
|
21
|
+
def service_password( password )
|
22
|
+
self.password_digest = Digest::SHA2.hexdigest( password )
|
23
|
+
DRbService.log.debug "Setting encrypted password for %p to "
|
24
|
+
end
|
25
|
+
|
26
|
+
end # module ClassMethods
|
27
|
+
|
28
|
+
|
29
|
+
### Overridden mixin callback -- add the ClassMethods to the including class
|
30
|
+
def self::included( klass )
|
31
|
+
super
|
32
|
+
klass.extend( ClassMethods )
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
### Authenticate using the specified +password+, calling the provided block if
|
37
|
+
### authentication succeeds. Raises a SecurityError if authentication fails. If
|
38
|
+
### no password is set, the block is called regardless of what the +password+ is.
|
39
|
+
def authenticate( password )
|
40
|
+
if digest = self.class.password_digest
|
41
|
+
if Digest::SHA2.hexdigest( password ) == digest
|
42
|
+
self.log.info "authentication successful"
|
43
|
+
@authenticated = true
|
44
|
+
yield
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
else
|
49
|
+
self.log.error "no password set -- authentication will always fail"
|
50
|
+
super
|
51
|
+
end
|
52
|
+
ensure
|
53
|
+
@authenticated = false
|
54
|
+
end
|
55
|
+
|
56
|
+
end # DRbService::PasswordAuthentication
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,426 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'erb'
|
5
|
+
require 'bigdecimal'
|
6
|
+
require 'date'
|
7
|
+
|
8
|
+
require 'drbservice'
|
9
|
+
|
10
|
+
|
11
|
+
class DRbService
|
12
|
+
|
13
|
+
### A collection of ANSI color utility functions
|
14
|
+
module ANSIColorUtilities
|
15
|
+
|
16
|
+
# Set some ANSI escape code constants (Shamelessly stolen from Perl's
|
17
|
+
# Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
|
18
|
+
ANSI_ATTRIBUTES = {
|
19
|
+
'clear' => 0,
|
20
|
+
'reset' => 0,
|
21
|
+
'bold' => 1,
|
22
|
+
'dark' => 2,
|
23
|
+
'underline' => 4,
|
24
|
+
'underscore' => 4,
|
25
|
+
'blink' => 5,
|
26
|
+
'reverse' => 7,
|
27
|
+
'concealed' => 8,
|
28
|
+
|
29
|
+
'black' => 30, 'on_black' => 40,
|
30
|
+
'red' => 31, 'on_red' => 41,
|
31
|
+
'green' => 32, 'on_green' => 42,
|
32
|
+
'yellow' => 33, 'on_yellow' => 43,
|
33
|
+
'blue' => 34, 'on_blue' => 44,
|
34
|
+
'magenta' => 35, 'on_magenta' => 45,
|
35
|
+
'cyan' => 36, 'on_cyan' => 46,
|
36
|
+
'white' => 37, 'on_white' => 47
|
37
|
+
}
|
38
|
+
|
39
|
+
###############
|
40
|
+
module_function
|
41
|
+
###############
|
42
|
+
|
43
|
+
### Create a string that contains the ANSI codes specified and return it
|
44
|
+
def ansi_code( *attributes )
|
45
|
+
attributes.flatten!
|
46
|
+
attributes.collect! {|at| at.to_s }
|
47
|
+
return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
|
48
|
+
attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
|
49
|
+
|
50
|
+
if attributes.empty?
|
51
|
+
return ''
|
52
|
+
else
|
53
|
+
return "\e[%sm" % attributes
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
### Colorize the given +string+ with the specified +attributes+ and return it, handling
|
59
|
+
### line-endings, color reset, etc.
|
60
|
+
def colorize( *args )
|
61
|
+
string = ''
|
62
|
+
|
63
|
+
if block_given?
|
64
|
+
string = yield
|
65
|
+
else
|
66
|
+
string = args.shift
|
67
|
+
end
|
68
|
+
|
69
|
+
ending = string[/(\s)$/] || ''
|
70
|
+
string = string.rstrip
|
71
|
+
|
72
|
+
return ansi_code( args.flatten ) + string + ansi_code( 'reset' ) + ending
|
73
|
+
end
|
74
|
+
|
75
|
+
end # module ANSIColorUtilities
|
76
|
+
|
77
|
+
|
78
|
+
#
|
79
|
+
# A alternate formatter for Logger instances.
|
80
|
+
#
|
81
|
+
# == Usage
|
82
|
+
#
|
83
|
+
# require 'drbservice/utils'
|
84
|
+
# DRbService.logger.formatter = DRbService::LogFormatter.new( DRbService.logger )
|
85
|
+
#
|
86
|
+
# == Version
|
87
|
+
#
|
88
|
+
# $Id: utils.rb,v 87bc5aa9e2be 2011/08/29 21:05:42 ged $
|
89
|
+
#
|
90
|
+
# == Authors
|
91
|
+
#
|
92
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
93
|
+
#
|
94
|
+
# :include: LICENSE
|
95
|
+
#
|
96
|
+
#--
|
97
|
+
#
|
98
|
+
# Please see the file LICENSE in the 'docs' directory for licensing details.
|
99
|
+
#
|
100
|
+
class LogFormatter < Logger::Formatter
|
101
|
+
|
102
|
+
# The format to output unless debugging is turned on
|
103
|
+
DEFAULT_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"
|
104
|
+
|
105
|
+
# The format to output if debugging is turned on
|
106
|
+
DEFAULT_DEBUG_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"
|
107
|
+
|
108
|
+
|
109
|
+
### Initialize the formatter with a reference to the logger so it can check for log level.
|
110
|
+
def initialize( logger, format=DEFAULT_FORMAT, debug=DEFAULT_DEBUG_FORMAT ) # :notnew:
|
111
|
+
@logger = logger
|
112
|
+
@format = format
|
113
|
+
@debug_format = debug
|
114
|
+
|
115
|
+
super()
|
116
|
+
end
|
117
|
+
|
118
|
+
######
|
119
|
+
public
|
120
|
+
######
|
121
|
+
|
122
|
+
# The Logger object associated with the formatter
|
123
|
+
attr_accessor :logger
|
124
|
+
|
125
|
+
# The logging format string
|
126
|
+
attr_accessor :format
|
127
|
+
|
128
|
+
# The logging format string that's used when outputting in debug mode
|
129
|
+
attr_accessor :debug_format
|
130
|
+
|
131
|
+
|
132
|
+
### Log using either the DEBUG_FORMAT if the associated logger is at ::DEBUG level or
|
133
|
+
### using FORMAT if it's anything less verbose.
|
134
|
+
def call( severity, time, progname, msg )
|
135
|
+
args = [
|
136
|
+
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
137
|
+
time.usec, # %2$d
|
138
|
+
Process.pid, # %3$d
|
139
|
+
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
140
|
+
severity, # %5$s
|
141
|
+
progname, # %6$s
|
142
|
+
msg # %7$s
|
143
|
+
]
|
144
|
+
|
145
|
+
if @logger.level == Logger::DEBUG
|
146
|
+
return self.debug_format % args
|
147
|
+
else
|
148
|
+
return self.format % args
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end # class LogFormatter
|
152
|
+
|
153
|
+
|
154
|
+
#
|
155
|
+
# A ANSI-colorized formatter for Logger instances.
|
156
|
+
#
|
157
|
+
# == Usage
|
158
|
+
#
|
159
|
+
# require 'drbservice/utils'
|
160
|
+
# DRbService.logger.formatter = DRbService::ColorLogFormatter.new( DRbService.logger )
|
161
|
+
#
|
162
|
+
# == Version
|
163
|
+
#
|
164
|
+
# $Id: utils.rb,v 87bc5aa9e2be 2011/08/29 21:05:42 ged $
|
165
|
+
#
|
166
|
+
# == Authors
|
167
|
+
#
|
168
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
169
|
+
#
|
170
|
+
# :include: LICENSE
|
171
|
+
#
|
172
|
+
#--
|
173
|
+
#
|
174
|
+
# Please see the file LICENSE in the 'docs' directory for licensing details.
|
175
|
+
#
|
176
|
+
class ColorLogFormatter < Logger::Formatter
|
177
|
+
extend DRbService::ANSIColorUtilities
|
178
|
+
|
179
|
+
# Color settings
|
180
|
+
LEVEL_FORMATS = {
|
181
|
+
:debug => colorize( :bold, :black ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"},
|
182
|
+
:info => colorize( :normal ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
|
183
|
+
:warn => colorize( :bold, :yellow ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
|
184
|
+
:error => colorize( :red ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
|
185
|
+
:fatal => colorize( :bold, :red, :on_white ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
|
186
|
+
}
|
187
|
+
|
188
|
+
|
189
|
+
### Initialize the formatter with a reference to the logger so it can check for log level.
|
190
|
+
def initialize( logger, settings={} ) # :notnew:
|
191
|
+
settings = LEVEL_FORMATS.merge( settings )
|
192
|
+
|
193
|
+
@logger = logger
|
194
|
+
@settings = settings
|
195
|
+
|
196
|
+
super()
|
197
|
+
end
|
198
|
+
|
199
|
+
######
|
200
|
+
public
|
201
|
+
######
|
202
|
+
|
203
|
+
# The Logger object associated with the formatter
|
204
|
+
attr_accessor :logger
|
205
|
+
|
206
|
+
# The formats, by level
|
207
|
+
attr_accessor :settings
|
208
|
+
|
209
|
+
|
210
|
+
### Log using the format associated with the severity
|
211
|
+
def call( severity, time, progname, msg )
|
212
|
+
args = [
|
213
|
+
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
214
|
+
time.usec, # %2$d
|
215
|
+
Process.pid, # %3$d
|
216
|
+
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
217
|
+
severity, # %5$s
|
218
|
+
progname, # %6$s
|
219
|
+
msg # %7$s
|
220
|
+
]
|
221
|
+
|
222
|
+
return self.settings[ severity.downcase.to_sym ] % args
|
223
|
+
end
|
224
|
+
end # class LogFormatter
|
225
|
+
|
226
|
+
|
227
|
+
#
|
228
|
+
# An alternate formatter for Logger instances that outputs +div+ HTML
|
229
|
+
# fragments.
|
230
|
+
#
|
231
|
+
# == Usage
|
232
|
+
#
|
233
|
+
# require 'drbservice/utils'
|
234
|
+
# DRbService.logger.formatter = DRbService::HtmlLogFormatter.new( DRbService.logger )
|
235
|
+
#
|
236
|
+
# == Version
|
237
|
+
#
|
238
|
+
# $Id: utils.rb,v 87bc5aa9e2be 2011/08/29 21:05:42 ged $
|
239
|
+
#
|
240
|
+
# == Authors
|
241
|
+
#
|
242
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
243
|
+
#
|
244
|
+
# :include: LICENSE
|
245
|
+
#
|
246
|
+
#--
|
247
|
+
#
|
248
|
+
# Please see the file LICENSE in the 'docs' directory for licensing details.
|
249
|
+
#
|
250
|
+
class HtmlLogFormatter < Logger::Formatter
|
251
|
+
include ERB::Util # for html_escape()
|
252
|
+
|
253
|
+
# The default HTML fragment that'll be used as the template for each log message.
|
254
|
+
HTML_LOG_FORMAT = %q{
|
255
|
+
<div class="log-message %5$s">
|
256
|
+
<span class="log-time">%1$s.%2$06d</span>
|
257
|
+
[
|
258
|
+
<span class="log-pid">%3$d</span>
|
259
|
+
/
|
260
|
+
<span class="log-tid">%4$s</span>
|
261
|
+
]
|
262
|
+
<span class="log-level">%5$s</span>
|
263
|
+
:
|
264
|
+
<span class="log-name">%6$s</span>
|
265
|
+
<span class="log-message-text">%7$s</span>
|
266
|
+
</div>
|
267
|
+
}
|
268
|
+
|
269
|
+
### Override the logging formats with ones that generate HTML fragments
|
270
|
+
def initialize( logger, format=HTML_LOG_FORMAT ) # :notnew:
|
271
|
+
@logger = logger
|
272
|
+
@format = format
|
273
|
+
super()
|
274
|
+
end
|
275
|
+
|
276
|
+
|
277
|
+
######
|
278
|
+
public
|
279
|
+
######
|
280
|
+
|
281
|
+
# The HTML fragment that will be used as a format() string for the log
|
282
|
+
attr_accessor :format
|
283
|
+
|
284
|
+
|
285
|
+
### Return a log message composed out of the arguments formatted using the
|
286
|
+
### formatter's format string
|
287
|
+
def call( severity, time, progname, msg )
|
288
|
+
args = [
|
289
|
+
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
290
|
+
time.usec, # %2$d
|
291
|
+
Process.pid, # %3$d
|
292
|
+
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
293
|
+
severity.downcase, # %5$s
|
294
|
+
progname, # %6$s
|
295
|
+
html_escape( msg ).gsub(/\n/, '<br />') # %7$s
|
296
|
+
]
|
297
|
+
|
298
|
+
return self.format % args
|
299
|
+
end
|
300
|
+
|
301
|
+
end # class HtmlLogFormatter
|
302
|
+
|
303
|
+
|
304
|
+
### DRbService logging methods and data.
|
305
|
+
module Logging
|
306
|
+
|
307
|
+
# Mapping of symbols to logging levels
|
308
|
+
LEVEL = {
|
309
|
+
:debug => Logger::DEBUG,
|
310
|
+
:info => Logger::INFO,
|
311
|
+
:warn => Logger::WARN,
|
312
|
+
:error => Logger::ERROR,
|
313
|
+
:fatal => Logger::FATAL,
|
314
|
+
}
|
315
|
+
|
316
|
+
|
317
|
+
### Inclusion callback: Add logging methods and instance variables to
|
318
|
+
### the Module +mod+.
|
319
|
+
def self::included( mod )
|
320
|
+
|
321
|
+
# Logging class instance variables
|
322
|
+
default_logger = Logger.new( $stderr )
|
323
|
+
default_logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
|
324
|
+
formatter = DRbService::LogFormatter.new( default_logger )
|
325
|
+
default_logger.formatter = formatter
|
326
|
+
|
327
|
+
mod.instance_variable_set( :@default_logger, default_logger )
|
328
|
+
mod.instance_variable_set( :@default_log_formatter, formatter )
|
329
|
+
mod.instance_variable_set( :@logger, default_logger )
|
330
|
+
|
331
|
+
# Accessors
|
332
|
+
class << mod
|
333
|
+
include DRbService::Logging::ClassMethods
|
334
|
+
|
335
|
+
# The log formatter that will be used when the logging subsystem is reset
|
336
|
+
attr_accessor :default_log_formatter
|
337
|
+
|
338
|
+
# The logger that will be used when the logging subsystem is reset
|
339
|
+
attr_accessor :default_logger
|
340
|
+
|
341
|
+
# The logger that's currently in effect
|
342
|
+
attr_accessor :logger
|
343
|
+
alias_method :log, :logger
|
344
|
+
alias_method :log=, :logger=
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|
348
|
+
|
349
|
+
|
350
|
+
### A collection of class methods that will get added as class method to anything that
|
351
|
+
### includes Logging.
|
352
|
+
module ClassMethods
|
353
|
+
|
354
|
+
### Reset the global logger object to the default
|
355
|
+
def reset_logger
|
356
|
+
self.logger = self.default_logger
|
357
|
+
self.logger.level = Logger::WARN
|
358
|
+
self.logger.formatter = self.default_log_formatter
|
359
|
+
end
|
360
|
+
|
361
|
+
|
362
|
+
### Returns +true+ if the global logger has not been set to something other than
|
363
|
+
### the default one.
|
364
|
+
def using_default_logger?
|
365
|
+
return self.logger == self.default_logger
|
366
|
+
end
|
367
|
+
|
368
|
+
|
369
|
+
### Return the library's version string
|
370
|
+
def version_string( include_buildnum=false )
|
371
|
+
vstring = "%s %s" % [ self.name, self.const_get(:VERSION) ]
|
372
|
+
if include_buildnum
|
373
|
+
rev = self.const_get(:REVISION)[/: ([[:xdigit:]]+)/, 1] rescue '0'
|
374
|
+
vstring << " (build %s)" % [ rev ]
|
375
|
+
end
|
376
|
+
return vstring
|
377
|
+
end
|
378
|
+
|
379
|
+
end # module ClassMethods
|
380
|
+
|
381
|
+
|
382
|
+
### A logging proxy class that wraps calls to the logger into calls that include
|
383
|
+
### the name of the calling class.
|
384
|
+
class ClassNameProxy # :nodoc:
|
385
|
+
|
386
|
+
### Create a new proxy for the given +klass+.
|
387
|
+
def initialize( klass, force_debug=false )
|
388
|
+
@classname = klass.name
|
389
|
+
@force_debug = force_debug
|
390
|
+
end
|
391
|
+
|
392
|
+
### Delegate calls the global logger with the class name as the 'progname'
|
393
|
+
### argument.
|
394
|
+
def method_missing( sym, msg=nil, &block )
|
395
|
+
return super unless LEVEL.key?( sym )
|
396
|
+
sym = :debug if @force_debug
|
397
|
+
DRbService.logger.add( LEVEL[sym], msg, @classname, &block )
|
398
|
+
end
|
399
|
+
end # ClassNameProxy
|
400
|
+
|
401
|
+
|
402
|
+
### Copy constructor -- clear the original's log proxy.
|
403
|
+
def initialize_copy( original )
|
404
|
+
@log_proxy = @log_debug_proxy = nil
|
405
|
+
super
|
406
|
+
end
|
407
|
+
|
408
|
+
|
409
|
+
### Return the proxied logger.
|
410
|
+
def log
|
411
|
+
@log_proxy ||= ClassNameProxy.new( self.class )
|
412
|
+
end
|
413
|
+
|
414
|
+
|
415
|
+
### Return a proxied "debug" logger that ignores other level specification.
|
416
|
+
def log_debug
|
417
|
+
@log_debug_proxy ||= ClassNameProxy.new( self.class, true )
|
418
|
+
end
|
419
|
+
|
420
|
+
end # module Logging
|
421
|
+
|
422
|
+
|
423
|
+
end # class DRbService
|
424
|
+
|
425
|
+
# vim: set nosta noet ts=4 sw=4:
|
426
|
+
|