arpitjain11-rubycas-server 0.8.0.20090612

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 +272 -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/hoe.rb +78 -0
  11. data/config/requirements.rb +15 -0
  12. data/config.example.yml +544 -0
  13. data/config.ru +38 -0
  14. data/custom_views.example.rb +11 -0
  15. data/lib/casserver/authenticators/active_directory_ldap.rb +11 -0
  16. data/lib/casserver/authenticators/base.rb +48 -0
  17. data/lib/casserver/authenticators/client_certificate.rb +46 -0
  18. data/lib/casserver/authenticators/google.rb +54 -0
  19. data/lib/casserver/authenticators/ldap.rb +147 -0
  20. data/lib/casserver/authenticators/ntlm.rb +88 -0
  21. data/lib/casserver/authenticators/open_id.rb +22 -0
  22. data/lib/casserver/authenticators/sql.rb +102 -0
  23. data/lib/casserver/authenticators/sql_encrypted.rb +76 -0
  24. data/lib/casserver/authenticators/sql_md5.rb +19 -0
  25. data/lib/casserver/authenticators/sql_rest_auth.rb +77 -0
  26. data/lib/casserver/authenticators/test.rb +19 -0
  27. data/lib/casserver/cas.rb +322 -0
  28. data/lib/casserver/conf.rb +75 -0
  29. data/lib/casserver/controllers.rb +457 -0
  30. data/lib/casserver/load_picnic.rb +19 -0
  31. data/lib/casserver/localization.rb +82 -0
  32. data/lib/casserver/models.rb +265 -0
  33. data/lib/casserver/postambles.rb +174 -0
  34. data/lib/casserver/utils.rb +30 -0
  35. data/lib/casserver/version.rb +9 -0
  36. data/lib/casserver/views.rb +245 -0
  37. data/lib/casserver.rb +58 -0
  38. data/lib/rubycas-server/version.rb +1 -0
  39. data/lib/rubycas-server.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,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
@@ -0,0 +1,30 @@
1
+ # Misc utility function used throughout by the RubyCAS-server.
2
+ module CASServer
3
+ module Utils
4
+ def random_string(max_length = 29)
5
+ rg = Crypt::ISAAC.new
6
+ max = 4294619050
7
+ r = "#{Time.now.to_i}r%X%X%X%X%X%X%X%X" %
8
+ [rg.rand(max), rg.rand(max), rg.rand(max), rg.rand(max),
9
+ rg.rand(max), rg.rand(max), rg.rand(max), rg.rand(max)]
10
+ r[0..max_length-1]
11
+ end
12
+ module_function :random_string
13
+
14
+ def log_controller_action(controller, params)
15
+ $LOG << "\n"
16
+
17
+ /`(.*)'/.match(caller[1])
18
+ method = $~[1]
19
+
20
+ if params.respond_to? :dup
21
+ params2 = params.dup
22
+ params2['password'] = '******' if params2['password']
23
+ else
24
+ params2 = params
25
+ end
26
+ $LOG.debug("Processing #{controller}::#{method} #{params2.inspect}")
27
+ end
28
+ module_function :log_controller_action
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ module CASServer
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 7
5
+ TINY = 99999
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end