kch-rubycas-server 0.8.0.20090715

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG.txt +1 -0
  2. data/History.txt +270 -0
  3. data/LICENSE.txt +504 -0
  4. data/Manifest.txt +85 -0
  5. data/PostInstall.txt +3 -0
  6. data/README.rdoc +26 -0
  7. data/Rakefile +4 -0
  8. data/bin/rubycas-server +13 -0
  9. data/bin/rubycas-server-ctl +9 -0
  10. data/config.example.yml +544 -0
  11. data/config.ru +38 -0
  12. data/config/hoe.rb +78 -0
  13. data/config/requirements.rb +15 -0
  14. data/custom_views.example.rb +11 -0
  15. data/lib/casserver.rb +58 -0
  16. data/lib/casserver/authenticators/active_directory_ldap.rb +11 -0
  17. data/lib/casserver/authenticators/base.rb +48 -0
  18. data/lib/casserver/authenticators/client_certificate.rb +46 -0
  19. data/lib/casserver/authenticators/google.rb +54 -0
  20. data/lib/casserver/authenticators/ldap.rb +147 -0
  21. data/lib/casserver/authenticators/ntlm.rb +88 -0
  22. data/lib/casserver/authenticators/open_id.rb +22 -0
  23. data/lib/casserver/authenticators/sql.rb +102 -0
  24. data/lib/casserver/authenticators/sql_encrypted.rb +77 -0
  25. data/lib/casserver/authenticators/sql_md5.rb +19 -0
  26. data/lib/casserver/authenticators/sql_rest_auth.rb +77 -0
  27. data/lib/casserver/authenticators/test.rb +19 -0
  28. data/lib/casserver/cas.rb +322 -0
  29. data/lib/casserver/conf.rb +75 -0
  30. data/lib/casserver/controllers.rb +456 -0
  31. data/lib/casserver/load_picnic.rb +19 -0
  32. data/lib/casserver/localization.rb +82 -0
  33. data/lib/casserver/models.rb +265 -0
  34. data/lib/casserver/postambles.rb +174 -0
  35. data/lib/casserver/utils.rb +30 -0
  36. data/lib/casserver/version.rb +9 -0
  37. data/lib/casserver/views.rb +245 -0
  38. data/lib/rubycas-server.rb +1 -0
  39. data/lib/rubycas-server/version.rb +1 -0
  40. data/po/de_DE/rubycas-server.po +119 -0
  41. data/po/es_ES/rubycas-server.po +115 -0
  42. data/po/fr_FR/rubycas-server.po +116 -0
  43. data/po/ja_JP/rubycas-server.po +118 -0
  44. data/po/pl_PL/rubycas-server.po +115 -0
  45. data/po/pt_BR/rubycas-server.po +115 -0
  46. data/po/ru_RU/rubycas-server.po +110 -0
  47. data/po/rubycas-server.pot +104 -0
  48. data/public/themes/cas.css +121 -0
  49. data/public/themes/notice.png +0 -0
  50. data/public/themes/ok.png +0 -0
  51. data/public/themes/simple/bg.png +0 -0
  52. data/public/themes/simple/login_box_bg.png +0 -0
  53. data/public/themes/simple/logo.png +0 -0
  54. data/public/themes/simple/theme.css +28 -0
  55. data/public/themes/urbacon/bg.png +0 -0
  56. data/public/themes/urbacon/login_box_bg.png +0 -0
  57. data/public/themes/urbacon/logo.png +0 -0
  58. data/public/themes/urbacon/theme.css +33 -0
  59. data/public/themes/warning.png +0 -0
  60. data/resources/init.d.sh +58 -0
  61. data/script/console +10 -0
  62. data/script/destroy +14 -0
  63. data/script/generate +14 -0
  64. data/script/txt2html +82 -0
  65. data/setup.rb +1585 -0
  66. data/tasks/deployment.rake +34 -0
  67. data/tasks/environment.rake +7 -0
  68. data/tasks/localization.rake +11 -0
  69. data/tasks/website.rake +17 -0
  70. data/vendor/isaac_0.9.1/LICENSE +26 -0
  71. data/vendor/isaac_0.9.1/README +78 -0
  72. data/vendor/isaac_0.9.1/TODO +3 -0
  73. data/vendor/isaac_0.9.1/VERSIONS +3 -0
  74. data/vendor/isaac_0.9.1/crypt/ISAAC.rb +171 -0
  75. data/vendor/isaac_0.9.1/isaac.gemspec +39 -0
  76. data/vendor/isaac_0.9.1/setup.rb +596 -0
  77. data/vendor/isaac_0.9.1/test/TC_ISAAC.rb +76 -0
  78. metadata +193 -0
@@ -0,0 +1,19 @@
1
+ if File.exists?(picnic = File.expand_path(File.dirname(File.expand_path(__FILE__))+'/../../vendor/picnic/lib'))
2
+ puts "Loading picnic from #{picnic.inspect}..."
3
+ $: << picnic
4
+ elsif File.exists?(picnic = File.expand_path(File.dirname(File.expand_path(__FILE__))+'/../../../picnic/lib'))
5
+ puts "Loading picnic from #{picnic.inspect}..."
6
+ $: << picnic
7
+ else
8
+ puts "Loading picnic from rubygems..."
9
+ require 'rubygems'
10
+
11
+ begin
12
+ # Try to load dev version of picnic if available (for example 'zuk-picnic' from Github)
13
+ gem /^.*?-picnic$/
14
+ rescue Gem::LoadError
15
+ gem 'picnic'
16
+ end
17
+ end
18
+
19
+
@@ -0,0 +1,82 @@
1
+ require "gettext"
2
+ require "gettext/cgi"
3
+
4
+ module CASServer
5
+ include GetText
6
+ bindtextdomain("rubycas-server", :path => File.join(File.dirname(File.expand_path(__FILE__)), "../../locale"))
7
+
8
+ def service(*a)
9
+ GetText.locale = determine_locale
10
+ #puts GetText.locale.inspect
11
+ super(*a)
12
+ end
13
+
14
+ def determine_locale
15
+
16
+ source = nil
17
+ lang = case
18
+ when !input['lang'].blank?
19
+ source = "'lang' request variable"
20
+ cookies['lang'] = input['lang']
21
+ input['lang']
22
+ when !cookies['lang'].blank?
23
+ source = "'lang' cookie"
24
+ cookies['lang']
25
+ when !@env['HTTP_ACCEPT_LANGUAGE'].blank?
26
+ source = "'HTTP_ACCEPT_LANGUAGE' header"
27
+ lang = @env['HTTP_ACCEPT_LANGUAGE']
28
+ when !@env['HTTP_USER_AGENT'].blank? && @env['HTTP_USER_AGENT'] =~ /[^a-z]([a-z]{2}(-[a-z]{2})?)[^a-z]/i
29
+ source = "'HTTP_USER_AGENT' header"
30
+ $~[1]
31
+ when !$CONF['default_locale'].blank?
32
+ source = "'default_locale' config option"
33
+ $CONF[:default_locale]
34
+ else
35
+ source = "default"
36
+ "en"
37
+ end
38
+
39
+ $LOG.debug "Detected locale is #{lang.inspect} (from #{source})"
40
+
41
+ lang.gsub!('_','-')
42
+
43
+ # TODO: Need to confirm that this method of splitting the accepted
44
+ # language string is correct.
45
+ if lang =~ /[,;\|]/
46
+ langs = lang.split(/[,;\|]/)
47
+ else
48
+ langs = [lang]
49
+ end
50
+
51
+ # TODO: This method of selecting the desired language might not be
52
+ # standards-compliant. For example, http://www.w3.org/TR/ltli/
53
+ # suggests that de-de and de-*-DE might be acceptable identifiers
54
+ # for selecting various wildcards. The algorithm below does not
55
+ # currently support anything like this.
56
+
57
+ available = available_locales
58
+
59
+ # Try to pick a locale exactly matching the desired identifier, otherwise
60
+ # fall back to locale without region (i.e. given "en-US; de-DE", we would
61
+ # first look for "en-US", then "en", then "de-DE", then "de").
62
+
63
+ chosen_lang = nil
64
+ langs.each do |l|
65
+ a = available.find{|a| a == l || a =~ Regexp.new("#{l}-\w*")}
66
+ if a
67
+ chosen_lang = a
68
+ break
69
+ end
70
+ end
71
+
72
+ chosen_lang = "en" if chosen_lang.blank?
73
+
74
+ $LOG.debug "Chosen locale is #{chosen_lang.inspect}"
75
+
76
+ return chosen_lang
77
+ end
78
+
79
+ def available_locales
80
+ (Dir.glob(File.join(File.dirname(File.expand_path(__FILE__)), "../../locale/[a-z]*")).map{|path| File.basename(path)} << "en").uniq.collect{|l| l.gsub('_','-')}
81
+ end
82
+ end
@@ -0,0 +1,265 @@
1
+ require 'camping/ar'
2
+
3
+ module CASServer::Models
4
+
5
+ module Consumable
6
+ def consume!
7
+ self.consumed = Time.now
8
+ self.save!
9
+ end
10
+
11
+ def self.included(mod)
12
+ mod.extend(ClassMethods)
13
+ end
14
+
15
+ module ClassMethods
16
+ def cleanup(max_lifetime, max_unconsumed_lifetime)
17
+ transaction do
18
+ conditions = ["created_on < ? OR (consumed IS NULL AND created_on < ?)",
19
+ Time.now - max_lifetime,
20
+ Time.now - max_unconsumed_lifetime]
21
+ expired_tickets_count = count(:conditions => conditions)
22
+
23
+ $LOG.debug("Destroying #{expired_tickets_count} expired #{self.name.demodulize}"+
24
+ "#{'s' if expired_tickets_count > 1}.") if expired_tickets_count > 0
25
+
26
+ destroy_all(conditions)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class Ticket < Base
33
+ def to_s
34
+ ticket
35
+ end
36
+
37
+ def self.cleanup(max_lifetime)
38
+ transaction do
39
+ conditions = ["created_on < ?", Time.now - max_lifetime]
40
+ expired_tickets_count = count(:conditions => conditions)
41
+
42
+ $LOG.debug("Destroying #{expired_tickets_count} expired #{self.name.demodulize}"+
43
+ "#{'s' if expired_tickets_count > 1}.") if expired_tickets_count > 0
44
+
45
+ destroy_all(conditions)
46
+ end
47
+ end
48
+ end
49
+
50
+ class LoginTicket < Ticket
51
+ set_table_name 'casserver_lt'
52
+ include Consumable
53
+ end
54
+
55
+ class ServiceTicket < Ticket
56
+ set_table_name 'casserver_st'
57
+ include Consumable
58
+
59
+ belongs_to :granted_by_tgt,
60
+ :class_name => 'CASServer::Models::TicketGrantingTicket',
61
+ :foreign_key => :granted_by_tgt_id
62
+ has_one :proxy_granting_ticket,
63
+ :foreign_key => :created_by_st_id
64
+
65
+ def matches_service?(service)
66
+ CASServer::CAS.clean_service_url(self.service) ==
67
+ CASServer::CAS.clean_service_url(service)
68
+ end
69
+ end
70
+
71
+ class ProxyTicket < ServiceTicket
72
+ belongs_to :granted_by_pgt,
73
+ :class_name => 'CASServer::Models::ProxyGrantingTicket',
74
+ :foreign_key => :granted_by_pgt_id
75
+ end
76
+
77
+ class TicketGrantingTicket < Ticket
78
+ set_table_name 'casserver_tgt'
79
+
80
+ serialize :extra_attributes
81
+
82
+ has_many :granted_service_tickets,
83
+ :class_name => 'CASServer::Models::ServiceTicket',
84
+ :foreign_key => :granted_by_tgt_id
85
+ end
86
+
87
+ class ProxyGrantingTicket < Ticket
88
+ set_table_name 'casserver_pgt'
89
+ belongs_to :service_ticket
90
+ has_many :granted_proxy_tickets,
91
+ :class_name => 'CASServer::Models::ProxyTicket',
92
+ :foreign_key => :granted_by_pgt_id
93
+ end
94
+
95
+ class Error
96
+ attr_reader :code, :message
97
+
98
+ def initialize(code, message)
99
+ @code = code
100
+ @message = message
101
+ end
102
+
103
+ def to_s
104
+ message
105
+ end
106
+ end
107
+
108
+ class CreateCASServer < V 0.1
109
+ def self.up
110
+ if ActiveRecord::Base.connection.table_alias_length > 30
111
+ $LOG.info("Creating database with long table names...")
112
+
113
+ create_table :casserver_login_tickets, :force => true do |t|
114
+ t.column :ticket, :string, :null => false
115
+ t.column :created_on, :timestamp, :null => false
116
+ t.column :consumed, :datetime, :null => true
117
+ t.column :client_hostname, :string, :null => false
118
+ end
119
+
120
+ create_table :casserver_service_tickets, :force => true do |t|
121
+ t.column :ticket, :string, :null => false
122
+ t.column :service, :string, :null => false
123
+ t.column :created_on, :timestamp, :null => false
124
+ t.column :consumed, :datetime, :null => true
125
+ t.column :client_hostname, :string, :null => false
126
+ t.column :username, :string, :null => false
127
+ t.column :type, :string, :null => false
128
+ t.column :proxy_granting_ticket_id, :integer, :null => true
129
+ end
130
+
131
+ create_table :casserver_ticket_granting_tickets, :force => true do |t|
132
+ t.column :ticket, :string, :null => false
133
+ t.column :created_on, :timestamp, :null => false
134
+ t.column :client_hostname, :string, :null => false
135
+ t.column :username, :string, :null => false
136
+ end
137
+
138
+ create_table :casserver_proxy_granting_tickets, :force => true do |t|
139
+ t.column :ticket, :string, :null => false
140
+ t.column :created_on, :timestamp, :null => false
141
+ t.column :client_hostname, :string, :null => false
142
+ t.column :iou, :string, :null => false
143
+ t.column :service_ticket_id, :integer, :null => false
144
+ end
145
+ end
146
+ end
147
+
148
+ def self.down
149
+ if ActiveRecord::Base.connection.table_alias_length > 30
150
+ drop_table :casserver_proxy_granting_tickets
151
+ drop_table :casserver_ticket_granting_tickets
152
+ drop_table :casserver_service_tickets
153
+ drop_table :casserver_login_tickets
154
+ end
155
+ end
156
+ end
157
+
158
+ # Oracle table names cannot exceed 30 chars...
159
+ # See http://code.google.com/p/rubycas-server/issues/detail?id=15
160
+ class ShortenTableNames < V 0.5
161
+ def self.up
162
+ if ActiveRecord::Base.connection.table_alias_length > 30
163
+ $LOG.info("Shortening table names")
164
+ rename_table :casserver_login_tickets, :casserver_lt
165
+ rename_table :casserver_service_tickets, :casserver_st
166
+ rename_table :casserver_ticket_granting_tickets, :casserver_tgt
167
+ rename_table :casserver_proxy_granting_tickets, :casserver_pgt
168
+ else
169
+ create_table :casserver_lt, :force => true do |t|
170
+ t.column :ticket, :string, :null => false
171
+ t.column :created_on, :timestamp, :null => false
172
+ t.column :consumed, :datetime, :null => true
173
+ t.column :client_hostname, :string, :null => false
174
+ end
175
+
176
+ create_table :casserver_st, :force => true do |t|
177
+ t.column :ticket, :string, :null => false
178
+ t.column :service, :string, :null => false
179
+ t.column :created_on, :timestamp, :null => false
180
+ t.column :consumed, :datetime, :null => true
181
+ t.column :client_hostname, :string, :null => false
182
+ t.column :username, :string, :null => false
183
+ t.column :type, :string, :null => false
184
+ t.column :proxy_granting_ticket_id, :integer, :null => true
185
+ end
186
+
187
+ create_table :casserver_tgt, :force => true do |t|
188
+ t.column :ticket, :string, :null => false
189
+ t.column :created_on, :timestamp, :null => false
190
+ t.column :client_hostname, :string, :null => false
191
+ t.column :username, :string, :null => false
192
+ end
193
+
194
+ create_table :casserver_pgt, :force => true do |t|
195
+ t.column :ticket, :string, :null => false
196
+ t.column :created_on, :timestamp, :null => false
197
+ t.column :client_hostname, :string, :null => false
198
+ t.column :iou, :string, :null => false
199
+ t.column :service_ticket_id, :integer, :null => false
200
+ end
201
+ end
202
+ end
203
+
204
+ def self.down
205
+ if ActiveRecord::Base.connection.table_alias_length > 30
206
+ rename_table :casserver_lt, :cassserver_login_tickets
207
+ rename_table :casserver_st, :casserver_service_tickets
208
+ rename_table :casserver_tgt, :casserver_ticket_granting_tickets
209
+ rename_table :casserver_pgt, :casserver_proxy_granting_tickets
210
+ else
211
+ drop_table :casserver_pgt
212
+ drop_table :casserver_tgt
213
+ drop_table :casserver_st
214
+ drop_table :casserver_lt
215
+ end
216
+ end
217
+ end
218
+
219
+ class AddTgtToSt < V 0.7
220
+ def self.up
221
+ add_column :casserver_st, :tgt_id, :integer, :null => true
222
+ end
223
+
224
+ def self.down
225
+ remove_column :casserver_st, :tgt_id, :integer
226
+ end
227
+ end
228
+
229
+ class ChangeServiceToText < V 0.71
230
+ def self.up
231
+ # using change_column to change the column type from :string to :text
232
+ # doesn't seem to work, at least under MySQL, so we drop and re-create
233
+ # the column instead
234
+ remove_column :casserver_st, :service
235
+ say "WARNING: All existing service tickets are being deleted."
236
+ add_column :casserver_st, :service, :text
237
+ end
238
+
239
+ def self.down
240
+ change_column :casserver_st, :service, :string
241
+ end
242
+ end
243
+
244
+ class AddExtraAttributes < V 0.72
245
+ def self.up
246
+ add_column :casserver_tgt, :extra_attributes, :text
247
+ end
248
+
249
+ def self.down
250
+ remove_column :casserver_tgt, :extra_attributes
251
+ end
252
+ end
253
+
254
+ class RenamePgtForeignKeys < V 0.80
255
+ def self.up
256
+ rename_column :casserver_st, :proxy_granting_ticket_id, :granted_by_pgt_id
257
+ rename_column :casserver_st, :tgt_id, :granted_by_tgt_id
258
+ end
259
+
260
+ def self.down
261
+ rename_column :casserver_st, :granted_by_pgt_id, :proxy_granting_ticket_id
262
+ rename_column :casserver_st, :granted_by_tgt_id, :tgt_id
263
+ end
264
+ end
265
+ end
@@ -0,0 +1,174 @@
1
+ module CASServer
2
+ module Postambles
3
+
4
+ def webrick
5
+ require 'webrick/httpserver'
6
+ require 'webrick/https'
7
+ require 'camping/webrick'
8
+
9
+ # TODO: verify the certificate's validity
10
+ # example of how to do this is here: http://pablotron.org/download/ruri-20050331.rb
11
+
12
+ cert_path = $CONF.ssl_cert
13
+ key_path = $CONF.ssl_key || $CONF.ssl_cert
14
+ # look for the key in the ssl_cert if no ssl_key is specified
15
+
16
+ webrick_options = {:BindAddress => "0.0.0.0", :Port => $CONF.port}
17
+
18
+ unless cert_path.nil? && key_path.nil?
19
+ raise "'#{cert_path}' is not a valid ssl certificate. Your 'ssl_cert' configuration" +
20
+ " setting must be a path to a valid ssl certificate file." unless
21
+ File.exists? cert_path
22
+
23
+ raise "'#{key_path}' is not a valid ssl private key. Your 'ssl_key' configuration" +
24
+ " setting must be a path to a valid ssl private key file." unless
25
+ File.exists? key_path
26
+
27
+ cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
28
+ key = OpenSSL::PKey::RSA.new(File.read(key_path))
29
+
30
+ webrick_options[:SSLEnable] = true
31
+ webrick_options[:SSLVerifyClient] = ::OpenSSL::SSL::VERIFY_NONE
32
+ webrick_options[:SSLCertificate] = cert
33
+ webrick_options[:SSLPrivateKey] = key
34
+ end
35
+
36
+ begin
37
+ s = WEBrick::HTTPServer.new(webrick_options)
38
+ rescue Errno::EACCES
39
+ puts "\nThe server could not launch. Are you running on a privileged port? (e.g. port 443) If so, you must run the server as root."
40
+ exit 2
41
+ end
42
+
43
+ CASServer.create
44
+ s.mount "#{$CONF.uri_path}", WEBrick::CampingHandler, CASServer
45
+
46
+ puts "\n** CASServer is running at http#{webrick_options[:SSLEnable] ? 's' : ''}://#{Socket.gethostname}:#{$CONF.port}#{$CONF.uri_path} and logging to '#{$CONF.log[:file]}'\n\n"
47
+
48
+ # This lets Ctrl+C shut down your server
49
+ trap(:INT) do
50
+ s.shutdown
51
+ end
52
+ trap(:TERM) do
53
+ s.shutdown
54
+ end
55
+
56
+ if $DAEMONIZE
57
+ WEBrick::Daemon.start do
58
+ write_pid_file if $PID_FILE
59
+ s.start
60
+ clear_pid_file
61
+ end
62
+ else
63
+ s.start
64
+ end
65
+ end
66
+
67
+
68
+
69
+ def mongrel
70
+ require 'rubygems'
71
+ require 'mongrel/camping'
72
+
73
+ if $DAEMONIZE
74
+ # check if log and pid are writable before daemonizing, otherwise we won't be able to notify
75
+ # the user if we run into trouble later (since once daemonized, we can't write to stdout/stderr)
76
+ check_pid_writable if $PID_FILE
77
+ check_log_writable
78
+ end
79
+
80
+ CASServer.create
81
+
82
+ puts "\n** CASServer is starting. Look in '#{$CONF.log[:file]}' for further notices."
83
+
84
+ settings = {:host => "0.0.0.0", :log_file => $CONF.log[:file], :cwd => $CASSERVER_HOME}
85
+
86
+ # need to close all IOs before daemonizing
87
+ $LOG.close if $DAEMONIZE
88
+
89
+ begin
90
+ config = Mongrel::Configurator.new settings do
91
+ daemonize :log_file => $CONF.log[:file], :cwd => $CASSERVER_HOME if $DAEMONIZE
92
+
93
+ listener :port => $CONF.port do
94
+ uri $CONF.uri_path, :handler => Mongrel::Camping::CampingHandler.new(CASServer)
95
+ setup_signals
96
+ end
97
+ end
98
+ rescue Errno::EADDRINUSE
99
+ exit 1
100
+ end
101
+
102
+ config.run
103
+
104
+ CASServer.init_logger
105
+ CASServer.init_db_logger
106
+
107
+ if $DAEMONIZE && $PID_FILE
108
+ write_pid_file
109
+ unless File.exists? $PID_FILE
110
+ $LOG.error "CASServer could not start because pid file '#{$PID_FILE}' could not be created."
111
+ exit 1
112
+ end
113
+ end
114
+
115
+ puts "\n** CASServer is running at http://localhost:#{$CONF.port}#{$CONF.uri_path} and logging to '#{$CONF.log[:file]}'"
116
+ config.join
117
+
118
+ clear_pid_file
119
+
120
+ puts "\n** CASServer is stopped (#{Time.now})"
121
+ end
122
+
123
+
124
+ def fastcgi
125
+ require 'camping/fastcgi'
126
+ Dir.chdir('/srv/www/camping/casserver/')
127
+
128
+ CASServer.create
129
+ Camping::FastCGI.start(CASServer)
130
+ end
131
+
132
+
133
+ def cgi
134
+ CASServer.create
135
+ puts CASServer.run
136
+ end
137
+
138
+ private
139
+ def check_log_writable
140
+ log_file = $CONF.log['file']
141
+ begin
142
+ f = open(log_file, 'w')
143
+ rescue
144
+ $stderr.puts "Couldn't write to log file at '#{log_file}' (#{$!})."
145
+ exit 1
146
+ end
147
+ f.close
148
+ end
149
+
150
+ def check_pid_writable
151
+ $LOG.debug "Checking if pid file '#{$PID_FILE}' is writable"
152
+ begin
153
+ f = open($PID_FILE, 'w')
154
+ rescue
155
+ $stderr.puts "Couldn't write to log at '#{$PID_FILE}' (#{$!})."
156
+ exit 1
157
+ end
158
+ f.close
159
+ end
160
+
161
+ def write_pid_file
162
+ $LOG.debug "Writing pid '#{Process.pid}' to pid file '#{$PID_FILE}'"
163
+ open($PID_FILE, "w") { |file| file.write(Process.pid) }
164
+ end
165
+
166
+ def clear_pid_file
167
+ if $PID_FILE && File.exists?($PID_FILE)
168
+ $LOG.debug "Clearing pid file '#{$PID_FILE}'"
169
+ File.unlink $PID_FILE
170
+ end
171
+ end
172
+
173
+ end
174
+ end