bringing in godfat's redesigned authenticator architecture with per-class setups... also a whole bunch of whitespace changes

This commit is contained in:
Matt Zukowski 2010-02-01 14:04:42 -05:00
Родитель 79351dec4f 29a09c6b61
Коммит 691c58d721
55 изменённых файлов: 1163 добавлений и 1108 удалений

Просмотреть файл

@ -1 +1 @@
See History.txt
See History.txt

Просмотреть файл

@ -1,8 +1,8 @@
=== 0.8.0 :: In Progress...
* NEW:
* Support for localization via Ruby-GetText.
See http://code.google.com/p/rubycas-server/wiki/Localization
* Support for localization via Ruby-GetText.
See http://code.google.com/p/rubycas-server/wiki/Localization
for details. [antono]
* Switched to Picnic 0.8.x, so RubyCAS-Server is now based on Rack
and Camping 2.0 and is now compatible with Passenger Phusion
@ -11,7 +11,7 @@
* Re-licensed under the MIT License.
* FIXED:
* Fixed weird problems with loading controllers when using older versions of
* Fixed weird problems with loading controllers when using older versions of
activesupport and/or rubygems.
* Failure to connect to a service during a single sign out request is now
handled gracefully.
@ -22,7 +22,7 @@
=== 0.7.1 :: 2008-11-10
* Fixed dependency loading problems introduced by upstream changes in RubyGems
* Fixed dependency loading problems introduced by upstream changes in RubyGems
1.3.1.
=== 0.7.0 :: 2008-11-04
@ -34,18 +34,18 @@
to CAS clients alongside the username. For an example of how to do this see
the included SQL authenticator. Also have a look at:
http://groups.google.com/group/rubycas-server/browse_thread/thread/5eade3793cb590e9
Note that extra attributes of type other than String or Numeric are serialized
Note that extra attributes of type other than String or Numeric are serialized
into YAML format before being sent along to the client.
* Added an MD5-password version of the SQL authenticator for Drupal and any other
database that stores its passwords in hashed form (thanks malcolmm).
* Added new Google authenticator for authenticating against Google/GMail
accounts.
* CHANGED:
* Service URIs are now automatically normalized. For example, if the service
URI given to the server has a 'ticket' parameter, the ticket will now be
automatically stripped. This is to avert any possible issues raised by
misbehaving CAS clients (the CAS ticket should never be part of the service
* Service URIs are now automatically normalized. For example, if the service
URI given to the server has a 'ticket' parameter, the ticket will now be
automatically stripped. This is to avert any possible issues raised by
misbehaving CAS clients (the CAS ticket should never be part of the service
URI). Same goes for other CAS-related parameters like 'service', 'renew',
and 'gateway'. Additionally, the trailing '/' and '?' characters are
automatically stripped from URLs, since, for example, "http://google.com/"
@ -65,8 +65,8 @@
auto-indentation has been turned off). Apparently the whitespace was
causing problems with mod_auth_cas. See:
http://groups.google.com/group/rubycas-server/browse_thread/thread/e482fe09999b73d3
* When used without pre-authentication, the LDAP authenticator now tries to
bind by searching for the given username in the LDAP directory based on the
* When used without pre-authentication, the LDAP authenticator now tries to
bind by searching for the given username in the LDAP directory based on the
configured username_attribute. Prior to this change the authenticator
attempted to bind with the LDAP server by assuming that the username credential
matches the user's CN. This is no longer the case.
@ -74,12 +74,12 @@
are missing or incorrect) will now have HTTP status code 422. Internal server
errors (where the server rather than the client is at fault) have error 500.
Previously most responses had error code 200, regardless of their contents.
* FIXED:
* Fixed logout action to work properly with ActiveRecord 2.1 (eager loading behaviour
was changed upstream forcing a change to the way we look for ProxyGrantingTickets
to delete on logout).
* When running under Mongrel, the USR2 signal should now restart the server as
* When running under Mongrel, the USR2 signal should now restart the server as
expected -- however currently this only works when the server is running
in the foregaround. When daemonized, USR2 will shut down the server without
restarting (see issue #58).
@ -108,7 +108,7 @@
* An encryption-enabled version of the SQL authenticator is now
available. For more info have a look at:
http://code.google.com/p/rubycas-server/wiki/UsingTheSQLEncryptedAuthenticator
* Better compatibility with Oracle databases. The database migration
* Better compatibility with Oracle databases. The database migration
no longer tries to create tables with long names when long
table names are not supported by the underlying database connector
(issue #15).
@ -129,7 +129,7 @@
* Tickets generated by the server should now be a lot more secure.
The random string generator used for generating tickets now uses
Crypt::ISAAC. Tickets have also been extended in length; STs, PTs
and LTs can now extend up to 32 characters, and PGTs and PGT-IOUs
and LTs can now extend up to 32 characters, and PGTs and PGT-IOUs
up to 64.
=== 0.5.0 :: 2007-09-20
@ -138,8 +138,8 @@
login page is made with gateway=true as one of the parameters, the CAS
server will immediately redirect back to the target service along with
a service ticket if an SSO session exists for the user (or without a
service ticket if there is no pre-existing SSO session).
Note that if you are using RubyCAS-Client and want gatewaying, you will
service ticket if there is no pre-existing SSO session).
Note that if you are using RubyCAS-Client and want gatewaying, you will
need to upgrade it to 1.1.0 as gatewaying was broken in prior versions.
* If gateway=true is specified as part of the logout URI, the server will
log the user out and immediately redirect them back to the specified
@ -162,9 +162,9 @@
this new RubyCAS-Server version.
* Multiple authenticators can now be specified. During authentication,
credentials are presented to the first authenticator, then the second,
and so on, until the user is validated by any one authenticator or fails
and so on, until the user is validated by any one authenticator or fails
validation for all of them. [jzylks]
* When using webrick, you can now run with SSL disabled by omitting the
* When using webrick, you can now run with SSL disabled by omitting the
ssl_cert and ssl_key parameters.
* Changed incorrect MySQL example database configuration -- option should
be 'host:' not 'server:' (issue #22).
@ -177,11 +177,11 @@
LDAP server).
* The validate() method in your authenticators now receives a :service element
(in addition to :username, and :password). This is simply the service
url (if any) specified in the user's CAS request. If you call
url (if any) specified in the user's CAS request. If you call
read_standard_credentials(credentials) at the top of your validator, the value
will also be available as @service along with @username and @password.
* By request, a :username_prefix option has been added to the ldap
configuration. If entered, this string will be automatically prefixed to
* By request, a :username_prefix option has been added to the ldap
configuration. If entered, this string will be automatically prefixed to
the username entered by the user.
* A bug having to do with handling authenticator errors has been fixed.
Any authenticator error messages should now be correctly shown on the
@ -193,9 +193,9 @@
=== 0.4.1 :: 2007-06-07
* This release restores compatiblity with older versions of rubygems
(pre-0.9.0). To achieve this, we alias the 'gem' method to the old
(pre-0.9.0). To achieve this, we alias the 'gem' method to the old
'require_gem' if 'gem' is not already defined.
* rubycas-server-ctl will now quiety delete an orphaned .pid file
* rubycas-server-ctl will now quiety delete an orphaned .pid file
instead complaining loudly and refusing to start up.
* Fixed minor bug in rubycas-server-ctl that sometimes incorrectly reported
startup problems when in fact the server had started just fine.
@ -221,9 +221,9 @@
In the future we may allow autocomplete to be re-enabled using a
configuration setting.
* When the user visits the login page and is already authenticated (i.e. they
have a valid ticket granting cookie), a message is shown at the top
have a valid ticket granting cookie), a message is shown at the top
indicating that they are already logged in.
* sqlite3-ruby is no longer required by the gem as a dependency. The user
* sqlite3-ruby is no longer required by the gem as a dependency. The user
must now install it manually prior to installing rubycas-server. The
building of sqlite3 native extensions appears to be somewhat flakey
and probably defeats the original purpose of using it (which was
@ -242,9 +242,9 @@
However, other exceptions should still be raised when errors ought
not be recoverable (i.e. programming errors).
* Fixed serious vulnerability in LDAP authenticator where under some
cirumstances the user could just enter '*' as their username to match
any username. The LDAP authenticator will now refuse to process logins
with usernames that contain the characters * ( ) \ / and the NULL
cirumstances the user could just enter '*' as their username to match
any username. The LDAP authenticator will now refuse to process logins
with usernames that contain the characters * ( ) \ / and the NULL
character \0.
* Views are no longer xhtml-validated. Markaby's auto-validation was turned
off to allow for use of the autocomplete property on inputs, since this is
@ -259,7 +259,7 @@
* ruby-casserver now behaves more like a real command-line app, accepting
various command line arguments including -h (help), -v (version), -c (use
an alternate config.yml), and -d (daemonize, when using webrick or mongrel
an alternate config.yml), and -d (daemonize, when using webrick or mongrel
mode).
* Special characters in CAS XML responses are now properly encoded into XML
entities

Просмотреть файл

@ -3,7 +3,7 @@ History.txt
LICENSE.txt
Manifest.txt
PostInstall.txt
README.txt
README.rdoc
Rakefile
bin/rubycas-server
bin/rubycas-server-ctl
@ -32,6 +32,10 @@ lib/casserver/load_picnic.rb
lib/casserver/localization.rb
lib/casserver/models.rb
lib/casserver/postambles.rb
lib/casserver/template/erb/layout.html.erb
lib/casserver/template/erb/login.html.erb
lib/casserver/template/erb/login_form.html.erb
lib/casserver/template/erb/logout.html.erb
lib/casserver/utils.rb
lib/casserver/version.rb
lib/casserver/views.rb

230
Rakefile
Просмотреть файл

@ -1,115 +1,115 @@
require 'config/requirements'
require 'config/hoe' # setup Hoe + all gem configuration
Dir['tasks/**/*.rake'].each { |rake| load rake }
desc "generate a self signed SSL certificate (in order to get going easily)"
task :generate_ssl_certificate do
`mkdir -p ssl/newcerts ssl/private`
File.open("ssl/openssl.cnf", "w") do |f|
f.write <<-EOF
#
# OpenSSL configuration file.
#
# Establish working directory.
dir = .
[ ca ]
default_ca = CA_default
[ CA_default ]
serial = $dir/serial
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/cacert.pem
private_key = $dir/private/cakey.pem
default_days = 365
default_md = md5
preserve = no
email_in_dn = no
nameopt = default_ca
certopt = default_ca
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 1024 # Size of keys
default_keyfile = key.pem # name of generated keys
default_md = md5 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
# Variable name Prompt string
#---------------------- ----------------------------------
0.organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name (city, district)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
# Default values for the above, for consistency and less typing.
# Variable name Value
#------------------------------ ------------------------------
0.organizationName_default = The Sample Company
localityName_default = Metropolis
stateOrProvinceName_default = New York
countryName_default = US
commonName_default = localhost
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
EOF
end
`cd ssl && echo '01' > serial`
`cd ssl && touch index.txt`
puts
puts "When asked for a passphrase enter one, for example rubycas"
puts
`cd ssl && openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf`
`cd ssl && openssl req -new -nodes -out req.pem -config ./openssl.cnf`
`cd ssl && openssl ca -out cert.pem -config ./openssl.cnf -infiles req.pem`
puts
puts "If you are using Firefox and want to access the CAS server through localhost you need to add an exception:"
puts " 1. Go to Preferences > Advanced > Encryption > View Certificates"
puts " 2. Click the Tab Servers"
puts " 3. Click the Button Add Exception"
puts " 4. Enter https://localhost:<port> into the textfield and press Get Certificate"
puts " 5. Then press View"
puts " 6. Then press Confirm Security Exception"
end
desc "clear all generated files for SSL certificate"
task :clear_ssl_certificate do
`rm -rf ssl`
end
require 'config/requirements'
require 'config/hoe' # setup Hoe + all gem configuration
Dir['tasks/**/*.rake'].each { |rake| load rake }
desc "generate a self signed SSL certificate (in order to get going easily)"
task :generate_ssl_certificate do
`mkdir -p ssl/newcerts ssl/private`
File.open("ssl/openssl.cnf", "w") do |f|
f.write <<-EOF
#
# OpenSSL configuration file.
#
# Establish working directory.
dir = .
[ ca ]
default_ca = CA_default
[ CA_default ]
serial = $dir/serial
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/cacert.pem
private_key = $dir/private/cakey.pem
default_days = 365
default_md = md5
preserve = no
email_in_dn = no
nameopt = default_ca
certopt = default_ca
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 1024 # Size of keys
default_keyfile = key.pem # name of generated keys
default_md = md5 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
# Variable name Prompt string
#---------------------- ----------------------------------
0.organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name (city, district)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
# Default values for the above, for consistency and less typing.
# Variable name Value
#------------------------------ ------------------------------
0.organizationName_default = The Sample Company
localityName_default = Metropolis
stateOrProvinceName_default = New York
countryName_default = US
commonName_default = localhost
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
EOF
end
`cd ssl && echo '01' > serial`
`cd ssl && touch index.txt`
puts
puts "When asked for a passphrase enter one, for example rubycas"
puts
`cd ssl && openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.cnf`
`cd ssl && openssl req -new -nodes -out req.pem -config ./openssl.cnf`
`cd ssl && openssl ca -out cert.pem -config ./openssl.cnf -infiles req.pem`
puts
puts "If you are using Firefox and want to access the CAS server through localhost you need to add an exception:"
puts " 1. Go to Preferences > Advanced > Encryption > View Certificates"
puts " 2. Click the Tab Servers"
puts " 3. Click the Button Add Exception"
puts " 4. Enter https://localhost:<port> into the textfield and press Get Certificate"
puts " 5. Then press View"
puts " 6. Then press Confirm Security Exception"
end
desc "clear all generated files for SSL certificate"
task :clear_ssl_certificate do
`rm -rf ssl`
end

Просмотреть файл

@ -26,13 +26,17 @@ require 'picnic'
require 'casserver'
CASServer.create
hack = lambda{ |env|
ActiveRecord::Base.verify_active_connections!
CASServer.call(env)
}
if $CONF.uri_path
map($CONF.uri_path) do
map($CONF.uri_path) do
# FIXME: this probably isn't the smartest way of remapping the themes dir to uri_path/themes
use Rack::Static, $CONF[:static] if $CONF[:static]
run CASServer
end
run hack
end
else
run CASServer
run hack
end

Просмотреть файл

@ -34,6 +34,12 @@ def CASServer.create
CASServer::Models::Base.establish_connection($CONF.database) unless CASServer::Models::Base.connected?
CASServer::Models.create_schema
# setup all the authenticators
$AUTH.zip($CONF.authenticator).each_with_index{ |auth_conf, index|
auth, conf = auth_conf
auth.setup(conf.merge(:auth_index => index))
}
#TODO: these warnings should eventually be deleted
if $CONF.service_ticket_expiry
$LOG.warn "The 'service_ticket_expiry' option has been renamed to 'maximum_unused_service_ticket_lifetime'. Please make the necessary change to your config file!"

Просмотреть файл

@ -17,13 +17,13 @@ module Authlogic
class AES256
class << self
attr_writer :key
def encrypt(*tokens)
aes.encrypt
aes.key = @key
[aes.update(tokens.join) + aes.final].pack("m").chomp
end
def matches?(crypted, *tokens)
aes.decrypt
aes.key = @key
@ -31,7 +31,7 @@ module Authlogic
rescue OpenSSL::CipherError
false
end
private
def aes
raise ArgumentError.new("You must provide a key like #{name}.key = my_key before using the #{name}") if @key.blank?
@ -40,4 +40,4 @@ module Authlogic
end
end
end
end
end

Просмотреть файл

@ -48,12 +48,12 @@ module Authlogic
@cost ||= 10
end
attr_writer :cost
# Creates a BCrypt hash for the password passed.
def encrypt(*tokens)
::BCrypt::Password.create(join_tokens(tokens), :cost => cost)
end
# Does the hash match the tokens? Uses the same tokens that were used to encrypt.
def matches?(hash, *tokens)
$LOG.debug hash
@ -63,7 +63,7 @@ module Authlogic
return false if hash.blank?
hash == join_tokens(tokens)
end
# This method is used as a flag to tell Authlogic to "resave" the password upon a successful login, using the new cost
def cost_matches?(hash)
hash = new_from_hash(hash)
@ -73,12 +73,12 @@ module Authlogic
hash.cost == cost
end
end
private
def join_tokens(tokens)
tokens.flatten.join
end
def new_from_hash(hash)
begin
::BCrypt::Password.new(hash)
@ -89,4 +89,4 @@ module Authlogic
end
end
end
end
end

Просмотреть файл

@ -1,29 +1,29 @@
require "digest/md5"
module Authlogic
module CryptoProviders
# This class was made for the users transitioning from md5 based systems.
# I highly discourage using this crypto provider as it superbly inferior
# This class was made for the users transitioning from md5 based systems.
# I highly discourage using this crypto provider as it superbly inferior
# to your other options.
#
# Please use any other provider offered by Authlogic.
class MD5
class << self
attr_accessor :join_token
# The number of times to loop through the encryption.
def stretches
@stretches ||= 1
end
attr_writer :stretches
# Turns your raw password into a MD5 hash.
def encrypt(*tokens)
digest = tokens.flatten.join(join_token)
stretches.times { digest = Digest::MD5.hexdigest(digest) }
digest
end
# Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
def matches?(crypted, *tokens)
encrypt(*tokens) == crypted
@ -31,4 +31,4 @@ module Authlogic
end
end
end
end
end

Просмотреть файл

@ -10,13 +10,13 @@ module Authlogic
@join_token ||= "--"
end
attr_writer :join_token
# The number of times to loop through the encryption. This is ten because that is what restful_authentication defaults to.
def stretches
@stretches ||= 10
end
attr_writer :stretches
# Turns your raw password into a Sha1 hash.
def encrypt(*tokens)
tokens = tokens.flatten
@ -24,7 +24,7 @@ module Authlogic
stretches.times { digest = Digest::SHA1.hexdigest([digest, *tokens].join(join_token)) }
digest
end
# Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
def matches?(crypted, *tokens)
encrypt(*tokens) == crypted
@ -32,4 +32,4 @@ module Authlogic
end
end
end
end
end

Просмотреть файл

@ -26,20 +26,20 @@ module Authlogic
class Sha512
class << self
attr_accessor :join_token
# The number of times to loop through the encryption. This is ten because that is what restful_authentication defaults to.
def stretches
@stretches ||= 20
end
attr_writer :stretches
# Turns your raw password into a Sha512 hash.
def encrypt(*tokens)
digest = tokens.flatten.join(join_token)
stretches.times { digest = Digest::SHA512.hexdigest(digest) }
digest
end
# Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
def matches?(crypted, *tokens)
encrypt(*tokens) == crypted
@ -47,4 +47,4 @@ module Authlogic
end
end
end
end
end

Просмотреть файл

@ -1,24 +1,31 @@
module CASServer
module Authenticators
class Base
def self.setup opts
# this would be called at rubycas-server start-up,
# override this method to setup what you need,
# e.g. setup database connection.
# leave it empty if you don't need to setup something.
end
attr_accessor :options
attr_reader :username # make this accessible so that we can pick up any
attr_reader :username # make this accessible so that we can pick up any
# transformations done within the authenticator
def validate(credentials)
raise NotImplementedError, "This method must be implemented by a class extending #{self.class}"
end
def configure(options)
raise ArgumentError, "options must be a HashWithIndifferentAccess" unless options.kind_of? HashWithIndifferentAccess
@options = options.dup
@extra_attributes = {}
end
def extra_attributes
@extra_attributes
end
protected
def read_standard_credentials(credentials)
@username = credentials[:username]
@ -26,7 +33,7 @@ module CASServer
@service = credentials[:service]
@request = credentials[:request]
end
def extra_attributes_to_extract
if @options[:extra_attributes].kind_of? Array
attrs = @options[:extra_attributes]
@ -36,13 +43,13 @@ module CASServer
$LOG.error("Can't figure out attribute list from #{@options[:extra_attributes].inspect}. This must be an Aarray of column names or a comma-separated list.")
attrs = []
end
$LOG.debug("#{self.class.name} will try to extract the following extra_attributes: #{attrs.inspect}")
return attrs
end
end
end
class AuthenticatorError < Exception
end
end
end

Просмотреть файл

@ -9,7 +9,7 @@ require 'casserver/authenticators/base'
# fall back to some other authentication mechanism.
#
# Here's an example of how to use two chained authenticators in the config.yml
# file. The server will first use the ClientCertificate authenticator, and
# file. The server will first use the ClientCertificate authenticator, and
# only fall back to the SQL authenticator of the first one fails:
#
# authenticator:
@ -30,17 +30,17 @@ require 'casserver/authenticators/base'
class CASServer::Authenticators::ClientCertificate < CASServer::Authenticators::Base
def validate(credentials)
read_standard_credentials(credentials)
@client_cert = credentials[:request]['SSL_CLIENT_CERT']
# note that I haven't actually tested to see if SSL_CLIENT_CERT gets
# filled with data when a client cert is provided, but this should be
# the case at least in theory :)
return false if @client_cert.blank?
# IMPLEMENT SSL CERTIFICATE VALIDATION CODE HERE
return true # if SSL certificate is valid, false otherwise
end
end

Просмотреть файл

@ -4,7 +4,7 @@ require 'net/http'
require 'net/https'
require 'timeout'
# Validates Google accounts against Google's authentication service -- in other
# Validates Google accounts against Google's authentication service -- in other
# words, this authenticator allows users to log in to CAS using their
# Gmail/Google accounts.
class CASServer::Authenticators::Google < CASServer::Authenticators::Base
@ -12,19 +12,19 @@ class CASServer::Authenticators::Google < CASServer::Authenticators::Base
read_standard_credentials(credentials)
return false if @username.blank? || @password.blank?
auth_data = {
'Email' => @username,
'Passwd' => @password,
'service' => 'xapi',
'Email' => @username,
'Passwd' => @password,
'service' => 'xapi',
'source' => 'RubyCAS-Server',
'accountType' => 'HOSTED_OR_GOOGLE'
}
url = URI.parse('https://www.google.com/accounts/ClientLogin')
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
# TODO: make the timeout configurable
wait_seconds = 10
begin
@ -34,7 +34,7 @@ class CASServer::Authenticators::Google < CASServer::Authenticators::Base
req.set_form_data(auth_data,'&')
conn.request(req)
end
case res
when Net::HTTPSuccess
true

Просмотреть файл

@ -26,47 +26,47 @@ class CASServer::Authenticators::LDAP < CASServer::Authenticators::Base
read_standard_credentials(credentials)
return false if @password.blank?
raise CASServer::AuthenticatorError, "Cannot validate credentials because the authenticator hasn't yet been configured" unless @options
raise CASServer::AuthenticatorError, "Invalid LDAP authenticator configuration!" unless @options[:ldap]
raise CASServer::AuthenticatorError, "You must specify a server host in the LDAP configuration!" unless @options[:ldap][:host] || @options[:ldap][:server]
raise CASServer::AuthenticatorError, "The username '#{@username}' contains invalid characters." if (@username =~ /[*\(\)\0\/]/)
preprocess_username
@ldap = Net::LDAP.new
@options[:ldap][:host] ||= @options[:ldap][:server]
@ldap.host = @options[:ldap][:host]
@ldap.port = @options[:ldap][:port] if @options[:ldap][:port]
@ldap.encryption(@options[:ldap][:encryption].intern) if @options[:ldap][:encryption]
begin
if @options[:ldap][:auth_user]
bind_success = bind_by_username_with_preauthentication
else
bind_success = bind_by_username
end
return false unless bind_success
entry = find_user
extract_extra_attributes(entry)
return true
rescue Net::LDAP::LdapError => e
raise CASServer::AuthenticatorError,
"LDAP authentication failed with '#{e}'. Check your authenticator configuration."
end
end
protected
def default_username_attribute
"cn"
end
private
# Add prefix to username, if :username_prefix was specified in the :ldap config.
def preprocess_username
@ -78,34 +78,34 @@ class CASServer::Authenticators::LDAP < CASServer::Authenticators::Base
# added to the LDAP query for the username.
def bind_by_username
username_attribute = options[:ldap][:username_attribute] || default_username_attribute
@ldap.bind_as(:base => @options[:ldap][:base], :password => @password, :filter => user_filter)
end
# If an auth_user is specified, we will connect ("pre-authenticate") with the
# LDAP server using the authenticator account, and then attempt to bind as the
# user who is actually trying to authenticate. Note that you need to set up
# user who is actually trying to authenticate. Note that you need to set up
# the special authenticator account first. Also, auth_user must be the authenticator
# user's full CN, which is probably not the same as their username.
#
# This pre-authentication process is necessary because binding can only be done
# using the CN, so having just the username is not enough. We connect as auth_user,
# using the CN, so having just the username is not enough. We connect as auth_user,
# and then try to find the target user's CN based on the given username. Then we bind
# as the target user to validate their credentials.
def bind_by_username_with_preauthentication
raise CASServer::AuthenticatorError, "A password must be specified in the configuration for the authenticator user!" unless
raise CASServer::AuthenticatorError, "A password must be specified in the configuration for the authenticator user!" unless
@options[:ldap][:auth_password]
@ldap.authenticate(@options[:ldap][:auth_user], @options[:ldap][:auth_password])
@ldap.bind_as(:base => @options[:ldap][:base], :password => @password, :filter => user_filter)
end
# Combine the filter for finding the user with the optional extra filter specified in the config
# (if any).
def user_filter
username_attribute = options[:ldap][:username_attribute] || default_username_attribute
filter = Net::LDAP::Filter.eq(username_attribute, @username)
unless @options[:ldap][:filter].blank?
filter &= Net::LDAP::Filter.construct(@options[:ldap][:filter])
@ -113,14 +113,14 @@ class CASServer::Authenticators::LDAP < CASServer::Authenticators::Base
filter
end
# Finds the user based on the user_filter (this is called after authentication).
# We do this to make it possible to extract extra_attributes.
def find_user
results = @ldap.search( :base => options[:ldap][:base], :filter => user_filter)
return results.first
end
def extract_extra_attributes(ldap_entry)
@extra_attributes = {}
extra_attributes_to_extract.each do |attr|
@ -136,7 +136,7 @@ class CASServer::Authenticators::LDAP < CASServer::Authenticators::Base
end
end
end
if @extra_attributes.empty?
$LOG.warn("#{self.class}: Did not read any extra_attributes for user #{@username.inspect} even though an :extra_attributes option was provided.")
else

Просмотреть файл

@ -2,7 +2,7 @@
#
# I started working on this but run into a wall, so I am commiting what I've got
# done and leaving it here with hopes of one day finishing it.
#
#
# The main problem is that although I've got the Lan Manager/NTLM password hash,
# I'm not sure what to do with it. i.e. I need to check it against the AD or SMB
# server or something... maybe faking an SMB share connection and using the LM
@ -35,10 +35,10 @@ module CASServer
else
raise "Invalid NTLM reply from client."
end
if t1
$LOG.debug "T1: #{t1.inspect}"
# now put together a Type2 message asking for the client to send
# back NTLM credentials (LM hash and such)
t2 = Net::NTLM::Message::Type2.new
@ -46,11 +46,11 @@ module CASServer
t2.set_flag :NTLM
t2.context = 0x0000000000000000 # this can probably just be left unassigned
t2.challenge = 0x0123456789abcdef # this should be a random 8-byte integer
$LOG.debug "T2: #{t2.inspect}"
$LOG.debug "T2: #{t2.serialize}"
headers["WWW-Authenticate"] = "NTLM #{t2.encode64}"
# the client should respond to this with a Type3 message...
r('401', '', headers)
return
@ -58,7 +58,7 @@ module CASServer
# NOTE: for some reason the server never receives the T3 response, even though monitoring
# the HTTP traffic I can see that the client does send it back... there's probably
# another bug hiding somewhere here
lm_response = t3.lm_response
ntlm_response = t3.ntlm_response
username = t3.user
@ -67,8 +67,8 @@ module CASServer
# call would do it?
$LOG.debug "T3 LM: #{lm_response.inspect}"
$LOG.debug "T3 NTLM: #{ntlm_response.inspect}"
# assuming the authentication was successful, we'll now need to do something in the
# assuming the authentication was successful, we'll now need to do something in the
# controller acting as if we'd received correct login credentials (i.e. proceed as if
# CAS authentication was successful).... if authentication failed, then we should
# just fall back to old-school web-based authentication, asking the user to enter
@ -85,4 +85,4 @@ module CASServer
end
end
end
end
end

Просмотреть файл

@ -13,10 +13,10 @@ class CASServer::Authenticators::OpenID < CASServer::Authenticators::Base
def validate(credentials)
raise NotImplementedError, "The OpenID authenticator is not yet implemented. "+
"See http://code.google.com/p/rubycas-server/issues/detail?id=36 if you are interested in helping this along."
read_standard_credentials(credentials)
store = OpenID::Store::Memory.new
consumer = OpenID::Consumer.new({}, store)
end
end
end

Просмотреть файл

@ -7,15 +7,15 @@ rescue LoadError
require 'active_record'
end
# Authenticates against a plain SQL table.
#
# This assumes that all of your users are stored in a table that has a 'username'
# column and a 'password' column. When the user logs in, CAS conects to the
# database and looks for a matching username/password in the users table. If a
# Authenticates against a plain SQL table.
#
# This assumes that all of your users are stored in a table that has a 'username'
# column and a 'password' column. When the user logs in, CAS conects to the
# database and looks for a matching username/password in the users table. If a
# matching username and password is found, authentication is successful.
#
# Any database backend supported by ActiveRecord can be used.
#
#
# Config example:
#
# authenticator:
@ -24,7 +24,7 @@ end
# adapter: mysql
# database: some_database_with_users_table
# username: root
# password:
# password:
# server: localhost
# user_table: users
# username_column: username
@ -34,10 +34,10 @@ end
# provide the client with the authenticated user's username. However it is now
# possible for the server to provide the client with additional attributes.
# You can configure the SQL authenticator to provide data from additional
# columns in the users table by listing the names of the columns under the
# columns in the users table by listing the names of the columns under the
# 'extra_attributes' option. Note though that this functionality is experimental.
# It should work with RubyCAS-Client, but may or may not work with other CAS
# clients.
# clients.
#
# For example, with this configuration, the 'full_name' and 'access_level'
# columns will be provided to your CAS clients along with the username:
@ -51,43 +51,53 @@ end
# username_column: username
# password_column: password
# extra_attributes: full_name, access_level
#
#
class CASServer::Authenticators::SQL < CASServer::Authenticators::Base
def self.setup opts
raise CASServer::AuthenticatorError, "Invalid authenticator configuration!" unless opts[:database]
user_model_name = "CASUser_#{opts[:auth_index]}"
$LOG.debug "CREATING USER MODEL #{user_model_name}"
class_eval %{
class #{user_model_name} < ActiveRecord::Base
end
}
@user_model = const_get(user_model_name)
@user_model.establish_connection(opts[:database])
@user_model.set_table_name(opts[:user_table] || 'users')
end
def self.user_model
@user_model
end
def validate(credentials)
read_standard_credentials(credentials)
raise CASServer::AuthenticatorError, "Cannot validate credentials because the authenticator hasn't yet been configured" unless @options
user_model = establish_database_connection_if_necessary
raise_if_not_configured
user_model = self.class.user_model
username_column = @options[:username_column] || 'username'
password_column = @options[:password_column] || 'password'
results = user_model.find(:all, :conditions => ["#{username_column} = ? AND #{password_column} = ?", @username, @password])
if results.size > 0
$LOG.warn("#{self.class}: Multiple matches found for user #{@username.inspect}") if results.size > 1
unless @options[:extra_attributes].blank?
if results.size > 1
$LOG.warn("#{self.class}: Unable to extract extra_attributes because multiple matches were found for #{@username.inspect}")
else
user = results.first
@extra_attributes = {}
extra_attributes_to_extract.each do |col|
@extra_attributes[col] = user.send(col)
end
if @extra_attributes.empty?
$LOG.warn("#{self.class}: Did not read any extra_attributes for user #{@username.inspect} even though an :extra_attributes option was provided.")
else
$LOG.debug("#{self.class}: Read the following extra_attributes for user #{@username.inspect}: #{@extra_attributes.inspect}")
end
extract_extra(user)
log_extra
end
end
return true
else
return false
@ -95,25 +105,24 @@ class CASServer::Authenticators::SQL < CASServer::Authenticators::Base
end
protected
def establish_database_connection_if_necessary
raise CASServer::AuthenticatorError, "Invalid authenticator configuration!" unless @options[:database]
user_model_name = "CASUser_#{@options[:auth_index]}"
if self.class.const_defined?(user_model_name)
$LOG.debug "REUSING USER MODEL #{user_model_name}"
user_model = self.class.const_get(user_model_name)
else
$LOG.debug "CREATING USER MODEL #{user_model_name}"
self.class.class_eval %{
class #{user_model_name} < ActiveRecord::Base
end
}
user_model = self.class.const_get(user_model_name)
user_model.establish_connection(options[:database])
user_model.set_table_name @options[:user_table] || "users"
end
user_model
def raise_if_not_configured
raise CASServer::AuthenticatorError.new(
"Cannot validate credentials because the authenticator hasn't yet been configured"
) unless @options
end
end
def extract_extra user
@extra_attributes = {}
extra_attributes_to_extract.each do |col|
@extra_attributes[col] = user.send(col)
end
end
def log_extra
if @extra_attributes.empty?
$LOG.warn("#{self.class}: Did not read any extra_attributes for user #{@username.inspect} even though an :extra_attributes option was provided.")
else
$LOG.debug("#{self.class}: Read the following extra_attributes for user #{@username.inspect}: #{@extra_attributes.inspect}")
end
end
end

Просмотреть файл

@ -15,15 +15,15 @@ rescue LoadError
require 'active_record'
end
# This is a version of the SQL authenticator that works nicely with Authlogic.
# Passwords are encrypted the same way as it done in Authlogic.
# Before use you this, you MUST configure rest_auth_digest_streches and rest_auth_site_key in
# config.
# This is a version of the SQL authenticator that works nicely with Authlogic.
# Passwords are encrypted the same way as it done in Authlogic.
# Before use you this, you MUST configure rest_auth_digest_streches and rest_auth_site_key in
# config.
#
# Using this authenticator requires restful authentication plugin on rails (client) side.
#
# * git://github.com/binarylogic/authlogic.git
#
#
# Usage:
# authenticator:
@ -44,11 +44,10 @@ class CASServer::Authenticators::SQLAuthlogic < CASServer::Authenticators::SQL
def validate(credentials)
read_standard_credentials(credentials)
raise CASServer::AuthenticatorError, "Cannot validate credentials because the authenticator hasn't yet been configured" unless @options
user_model = establish_database_connection_if_necessary
raise_if_not_configured
user_model = self.class.user_model
username_column = @options[:username_column] || "login"
password_column = @options[:password_column] || "crypted_password"
salt_column = @options[:salt_column]
@ -70,17 +69,10 @@ class CASServer::Authenticators::SQLAuthlogic < CASServer::Authenticators::SQL
if results.size > 1
$LOG.warn("#{self.class}: Unable to extract extra_attributes because multiple matches were found for #{@username.inspect}")
else
@extra_attributes = {}
extra_attributes_to_extract.each do |col|
@extra_attributes[col] = user.send(col)
end
if @extra_attributes.empty?
$LOG.warn("#{self.class}: Did not read any extra_attributes for user #{@username.inspect} even though an :extra_attributes option was provided.")
else
$LOG.debug("#{self.class}: Read the following extra_attributes for user #{@username.inspect}: #{@extra_attributes.inspect}")
end
extract_extra(user)
log_extra
end
end

Просмотреть файл

@ -1,4 +1,4 @@
require 'casserver/authenticators/base'
require 'casserver/authenticators/sql'
require 'digest/sha1'
require 'digest/sha2'
@ -6,58 +6,15 @@ require 'digest/sha2'
$: << File.dirname(File.expand_path(__FILE__)) + "/../../../vendor/isaac_0.9.1"
require 'crypt/ISAAC'
begin
require 'active_record'
rescue LoadError
require 'rubygems'
require 'active_record'
end
# This is a more secure version of the SQL authenticator. Passwords are encrypted
# This is a more secure version of the SQL authenticator. Passwords are encrypted
# rather than being stored in plain text.
#
# Based on code contributed by Ben Mabey.
#
# Using this authenticator requires some configuration on the client side. Please see
# http://code.google.com/p/rubycas-server/wiki/UsingTheSQLEncryptedAuthenticator
class CASServer::Authenticators::SQLEncrypted < CASServer::Authenticators::Base
def validate(credentials)
read_standard_credentials(credentials)
raise CASServer::AuthenticatorError, "Cannot validate credentials because the authenticator hasn't yet been configured" unless @options
user_model = establish_database_connection_if_necessary
username_column = @options[:username_column] || "username"
encrypt_function = @options[:encrypt_function] || 'user.encrypted_password == Digest::SHA256.hexdigest("#{user.encryption_salt}::#{@password}")'
results = user_model.find(:all, :conditions => ["#{username_column} = ?", @username])
if results.size > 0
$LOG.warn("Multiple matches found for user '#{@username}'") if results.size > 1
user = results.first
unless @options[:extra_attributes].blank?
@extra_attributes = {}
extra_attributes_to_extract.each do |col|
@extra_attributes[col] = user.send(col)
end
if @extra_attributes.empty?
$LOG.warn("#{self.class}: Did not read any extra_attributes for user #{@username.inspect} even though an :extra_attributes option was provided.")
else
$LOG.debug("#{self.class}: Read the following extra_attributes for user #{@username.inspect}: #{@extra_attributes.inspect}")
end
end
return eval(encrypt_function)
else
return false
end
end
# Include this module into your application's user model.
class CASServer::Authenticators::SQLEncrypted < CASServer::Authenticators::SQL
# Include this module into your application's user model.
#
# Your model must have an 'encrypted_password' column where the password will be stored,
# and an 'encryption_salt' column that will be populated with a random string before
@ -67,40 +24,44 @@ class CASServer::Authenticators::SQLEncrypted < CASServer::Authenticators::Base
raise "#{self} should be inclued in an ActiveRecord class!" unless mod.respond_to?(:before_save)
mod.before_save :generate_encryption_salt
end
def encrypt(str)
generate_encryption_salt unless encryption_salt
Digest::SHA256.hexdigest("#{encryption_salt}::#{str}")
end
def password=(password)
self[:encrypted_password] = encrypt(password)
end
def generate_encryption_salt
self.encryption_salt = Digest::SHA1.hexdigest(Crypt::ISAAC.new.rand(2**31).to_s) unless
encryption_salt
end
end
protected
def establish_database_connection_if_necessary
raise CASServer::AuthenticatorError, "Invalid authenticator configuration!" unless @options[:database]
def self.setup opts
super(opts)
user_model.__send__(:include, EncryptedPassword)
end
user_model_name = "CASUser_#{@options[:auth_index]}"
if self.class.const_defined?(user_model_name)
user_model = self.class.const_get(user_model_name)
def validate(credentials)
read_standard_credentials(credentials)
raise_if_not_configured
user_model = self.class.user_model
username_column = @options[:username_column] || "username"
encrypt_function = @options[:encrypt_function] || 'user.encrypted_password == Digest::SHA256.hexdigest("#{user.encryption_salt}::#{@password}")'
results = user_model.find(:all, :conditions => ["#{username_column} = ?", @username])
if results.size > 0
$LOG.warn("Multiple matches found for user '#{@username}'") if results.size > 1
user = results.first
return eval(encrypt_function)
else
self.class.class_eval %{
class #{user_model_name} < ActiveRecord::Base
include EncryptedPassword
end
}
user_model = self.class.const_get(user_model_name)
user_model.set_table_name @options[:user_table] || "users"
user_model.establish_connection(options[:database])
return false
end
user_model
end
end

Просмотреть файл

@ -9,11 +9,11 @@ require 'digest/md5'
# Drupal, you should use 'name' for the :username_column config option, and
# 'pass' for the :password_column.
class CASServer::Authenticators::SQLMd5 < CASServer::Authenticators::SQL
protected
def read_standard_credentials(credentials)
super
@password = Digest::MD5.hexdigest(@password)
end
end
end

Просмотреть файл

@ -9,10 +9,10 @@ rescue LoadError
require 'active_record'
end
# This is a version of the SQL authenticator that works nicely with RestfulAuthentication.
# Passwords are encrypted the same way as it done in RestfulAuthentication.
# Before use you this, you MUST configure rest_auth_digest_streches and rest_auth_site_key in
# config.
# This is a version of the SQL authenticator that works nicely with RestfulAuthentication.
# Passwords are encrypted the same way as it done in RestfulAuthentication.
# Before use you this, you MUST configure rest_auth_digest_streches and rest_auth_site_key in
# config.
#
# Using this authenticator requires restful authentication plugin on rails (client) side.
#
@ -22,27 +22,26 @@ class CASServer::Authenticators::SQLRestAuth < CASServer::Authenticators::SQLEnc
def validate(credentials)
read_standard_credentials(credentials)
raise CASServer::AuthenticatorError, "Cannot validate credentials because the authenticator hasn't yet been configured" unless @options
raise_if_not_configured
user_model = self.class.user_model
user_model = establish_database_connection_if_necessary
username_column = @options[:username_column] || "email"
results = user_model.find(:all, :conditions => ["#{username_column} = ?", @username])
if results.size > 0
$LOG.warn("Multiple matches found for user '#{@username}'") if results.size > 1
user = results.first
return (user.crypted_password == user.encrypt(@password))
return (user.crypted_password == user.encrypt(@password))
else
return false
end
end
module EncryptedPassword
# XXX: this constants MUST be defined in config.
# XXX: this constants MUST be defined in config.
# For more details # look at restful-authentication docs.
#
REST_AUTH_DIGEST_STRETCHES = $CONF.rest_auth_digest_streches
@ -51,11 +50,11 @@ class CASServer::Authenticators::SQLRestAuth < CASServer::Authenticators::SQLEnc
def self.included(mod)
raise "#{self} should be inclued in an ActiveRecord class!" unless mod.respond_to?(:before_save)
end
def encrypt(password)
password_digest(password, self.salt)
end
def secure_digest(*args)
Digest::SHA1.hexdigest(args.flatten.join('--'))
end
@ -66,6 +65,6 @@ class CASServer::Authenticators::SQLRestAuth < CASServer::Authenticators::SQLEnc
digest = secure_digest(digest, salt, password, REST_AUTH_SITE_KEY)
end
digest
end
end
end
end

Просмотреть файл

@ -1,19 +1,19 @@
require 'casserver/authenticators/base'
# Dummy authenticator used for testing.
# Dummy authenticator used for testing.
# Accepts any username as valid as long as the password is "testpassword"; otherwise authentication fails.
# Raises an AuthenticationError when username is "do_error" (this is useful to test the Exception
# handling functionality).
class CASServer::Authenticators::Test < CASServer::Authenticators::Base
def validate(credentials)
read_standard_credentials(credentials)
raise CASServer::AuthenticatorError, "Username is 'do_error'!" if @username == 'do_error'
@extra_attributes[:test_string] = "testing!"
@extra_attributes[:test_numeric] = 123.45
@extra_attributes[:test_serialized] = {:foo => 'bar', :alpha => [1,2,3]}
return @password == "testpassword"
end
end

Просмотреть файл

@ -11,19 +11,19 @@ module CASServer::CAS
# 3.5 (login ticket)
lt = LoginTicket.new
lt.ticket = "LT-" + CASServer::Utils.random_string
lt.client_hostname = @env['HTTP_X_FORWARDED_FOR'] || @env['REMOTE_HOST'] || @env['REMOTE_ADDR']
lt.save!
$LOG.debug("Generated login ticket '#{lt.ticket}' for client" +
" at '#{lt.client_hostname}'")
lt
end
# Creates a TicketGrantingTicket for the given username. This is done when the user logs in
# for the first time to establish their SSO session (after their credentials have been validated).
#
# The optional 'extra_attributes' parameter takes a hash of additional attributes
# that will be sent along with the username in the CAS response to subsequent
# that will be sent along with the username in the CAS response to subsequent
# validation requests from clients.
def generate_ticket_granting_ticket(username, extra_attributes = {})
# 3.6 (ticket granting cookie/ticket)
@ -34,11 +34,11 @@ module CASServer::CAS
tgt.client_hostname = @env['HTTP_X_FORWARDED_FOR'] || @env['REMOTE_HOST'] || @env['REMOTE_ADDR']
tgt.save!
$LOG.debug("Generated ticket granting ticket '#{tgt.ticket}' for user" +
" '#{tgt.username}' at '#{tgt.client_hostname}'" +
" '#{tgt.username}' at '#{tgt.client_hostname}'" +
(extra_attributes.blank? ? "" : " with extra attributes #{extra_attributes.inspect}"))
tgt
end
def generate_service_ticket(service, username, tgt)
# 3.1 (service ticket)
st = ServiceTicket.new
@ -52,7 +52,7 @@ module CASServer::CAS
" for user '#{st.username}' at '#{st.client_hostname}'")
st
end
def generate_proxy_ticket(target_service, pgt)
# 3.2 (proxy ticket)
pt = ProxyTicket.new
@ -68,19 +68,19 @@ module CASServer::CAS
" ticket '#{pgt.ticket}'")
pt
end
def generate_proxy_granting_ticket(pgt_url, st)
uri = URI.parse(pgt_url)
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
# Here's what's going on here:
#
#
# 1. We generate a ProxyGrantingTicket (but don't store it in the database just yet)
# 2. Deposit the PGT and it's associated IOU at the proxy callback URL.
# 3. If the proxy callback URL responds with HTTP code 200, store the PGT and return it;
# otherwise don't save it and return nothing.
#
#
https.start do |conn|
path = uri.path.empty? ? '/' : uri.path
path += '?' + uri.query unless (uri.query.nil? || uri.query.empty?)
@ -90,12 +90,12 @@ module CASServer::CAS
pgt.iou = "PGTIOU-" + CASServer::Utils.random_string(57)
pgt.service_ticket_id = st.id
pgt.client_hostname = @env['HTTP_X_FORWARDED_FOR'] || @env['REMOTE_HOST'] || @env['REMOTE_ADDR']
# FIXME: The CAS protocol spec says to use 'pgt' as the parameter, but in practice
# the JA-SIG and Yale server implementations use pgtId. We'll go with the
# in-practice standard.
path += (uri.query.nil? || uri.query.empty? ? '?' : '&') + "pgtId=#{pgt.ticket}&pgtIou=#{pgt.iou}"
response = conn.request_get(path)
# TODO: follow redirects... 2.5.4 says that redirects MAY be followed
# NOTE: The following response codes are valid according to the JA-SIG implementation even without following redirects
@ -111,10 +111,10 @@ module CASServer::CAS
end
end
end
def validate_login_ticket(ticket)
$LOG.debug("Validating login ticket '#{ticket}'")
success = false
if ticket.nil?
error = _("Your login request did not include a login ticket. There may be a problem with the authentication system.")
@ -133,15 +133,15 @@ module CASServer::CAS
error = _("The login ticket you provided is invalid. There may be a problem with the authentication system.")
$LOG.warn "Invalid login ticket '#{ticket}'"
end
lt.consume! if lt
error
end
def validate_ticket_granting_ticket(ticket)
$LOG.debug("Validating ticket granting ticket '#{ticket}'")
if ticket.nil?
error = "No ticket granting ticket given."
$LOG.debug error
@ -156,13 +156,13 @@ module CASServer::CAS
error = "Invalid ticket granting ticket '#{ticket}' (no matching ticket found in the database)."
$LOG.warn(error)
end
[tgt, error]
end
def validate_service_ticket(service, ticket, allow_proxy_tickets = false)
$LOG.debug "Validating service/proxy ticket '#{ticket}' for service '#{service}'"
if service.nil? or ticket.nil?
error = Error.new(:INVALID_REQUEST, "Ticket or service parameter was missing in the request.")
$LOG.warn "#{error.code} - #{error.message}"
@ -187,18 +187,18 @@ module CASServer::CAS
error = Error.new(:INVALID_TICKET, "Ticket '#{ticket}' not recognized.")
$LOG.warn("#{error.code} - #{error.message}")
end
if st
st.consume!
end
[st, error]
end
def validate_proxy_ticket(service, ticket)
pt, error = validate_service_ticket(service, ticket, true)
if pt.kind_of?(CASServer::Models::ProxyTicket) && !error
if not pt.granted_by_pgt
error = Error.new(:INTERNAL_ERROR, "Proxy ticket '#{pt}' belonging to user '#{pt.username}' is not associated with a proxy granting ticket.")
@ -207,10 +207,10 @@ module CASServer::CAS
" (associated with proxy ticket '#{pt}' and belonging to user '#{pt.username}' is not associated with a service ticket.")
end
end
[pt, error]
end
def validate_proxy_granting_ticket(ticket)
if ticket.nil?
error = Error.new(:INVALID_REQUEST, "pgt parameter was missing in the request.")
@ -226,10 +226,10 @@ module CASServer::CAS
error = Error.new(:BAD_PGT, "Invalid proxy granting ticket '#{ticket}' (no matching ticket found in the database).")
$LOG.warn("#{error.code} - #{error.message}")
end
[pgt, error]
end
# Takes an existing ServiceTicket object (presumably pulled from the database)
# and sends a POST with logout information to the service that the ticket
# was generated for.
@ -240,13 +240,13 @@ module CASServer::CAS
uri = URI.parse(st.service)
http = Net::HTTP.new(uri.host, uri.port)
#http.use_ssl = true if uri.scheme = 'https'
time = Time.now
rand = CASServer::Utils.random_string
path = uri.path
path = '/' if path.empty?
req = Net::HTTP::Post.new(path)
req.set_form_data(
'logoutRequest' => %{<samlp:LogoutRequest ID="#{rand}" Version="2.0" IssueInstant="#{time.rfc2822}">
@ -254,11 +254,11 @@ module CASServer::CAS
<samlp:SessionIndex>#{st.ticket}</samlp:SessionIndex>
</samlp:LogoutRequest>}
)
begin
http.start do |conn|
response = conn.request(req)
if response.kind_of? Net::HTTPSuccess
$LOG.info "Logout notification successfully posted to #{st.service.inspect}."
return true
@ -272,14 +272,14 @@ module CASServer::CAS
return false
end
end
def service_uri_with_ticket(service, st)
raise ArgumentError, "Second argument must be a ServiceTicket!" unless st.kind_of? CASServer::Models::ServiceTicket
# This will choke with a URI::InvalidURIError if service URI is not properly URI-escaped...
# This exception is handled further upstream (i.e. in the controller).
service_uri = URI.parse(service)
if service.include? "?"
if service_uri.query.empty?
query_separator = ""
@ -289,11 +289,11 @@ module CASServer::CAS
else
query_separator = "?"
end
service_with_ticket = service + query_separator + "ticket=" + st.ticket
service_with_ticket
end
# Strips CAS-related parameters from a service URL and normalizes it,
# removing trailing / and ?. Also converts any spaces to +.
#
@ -310,16 +310,16 @@ module CASServer::CAS
['service', 'ticket', 'gateway', 'renew'].each do |p|
clean_service.sub!(Regexp.new("&?#{p}=[^&]*"), '')
end
clean_service.gsub!(/[\/\?&]$/, '') # remove trailing ?, /, or &
clean_service.gsub!('?&', '?')
clean_service.gsub!(' ', '+')
$LOG.debug("Cleaned dirty service URL #{dirty_service.inspect} to #{clean_service.inspect}") if
dirty_service != clean_service
return clean_service
end
module_function :clean_service_url
end

Просмотреть файл

@ -1,3 +1,6 @@
require 'active_support'
conf_defaults = {
:maximum_unused_login_ticket_lifetime => 5.minutes,
:maximum_unused_service_ticket_lifetime => 5.minutes, # CAS Protocol Spec, sec. 3.2.1 (recommended expiry time)
@ -29,7 +32,7 @@ unless $CONF[:authenticator]
your config file.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"
"
raise Picnic::Conf::Error, err
end
@ -39,6 +42,7 @@ begin
$CONF[:authenticator].each { |authenticator| $AUTH << authenticator[:class].constantize}
else
$AUTH << $CONF[:authenticator][:class].constantize
$CONF[:authenticator] = [$CONF[:authenticator]]
end
rescue NameError
if $CONF[:authenticator].instance_of? Array
@ -52,7 +56,6 @@ rescue NameError
require 'casserver/'+auth_rb
end
$AUTH << authenticator[:class].constantize
$CONF[:authenticator] = [$CONF[:authenticator]]
end
else
if $CONF[:authenticator][:source]

Просмотреть файл

@ -7,7 +7,7 @@ elsif File.exists?(picnic = File.expand_path(File.dirname(File.expand_path(__FIL
else
puts "Loading picnic from rubygems..."
require 'rubygems'
begin
# Try to load dev version of picnic if available (for example 'zuk-picnic' from Github)
gem /^.*?-picnic$/

Просмотреть файл

@ -4,13 +4,13 @@ require "gettext/cgi"
module CASServer
include GetText
bindtextdomain("rubycas-server", :path => File.join(File.dirname(File.expand_path(__FILE__)), "../../locale"))
def service(*a)
GetText.locale = determine_locale
#puts GetText.locale.inspect
super(*a)
end
def determine_locale
source = nil
@ -39,7 +39,7 @@ module CASServer
$LOG.debug "Detected locale is #{lang.inspect} (from #{source})"
lang.gsub!('_','-')
# TODO: Need to confirm that this method of splitting the accepted
# language string is correct.
if lang =~ /[,;\|]/
@ -47,35 +47,36 @@ module CASServer
else
langs = [lang]
end
# TODO: This method of selecting the desired language might not be
# standards-compliant. For example, http://www.w3.org/TR/ltli/
# suggests that de-de and de-*-DE might be acceptable identifiers
# for selecting various wildcards. The algorithm below does not
# currently support anything like this.
available = available_locales
# Try to pick a locale exactly matching the desired identifier, otherwise
# fall back to locale without region (i.e. given "en-US; de-DE", we would
# first look for "en-US", then "en", then "de-DE", then "de").
chosen_lang = nil
langs.each do |l|
a = available.find{|a| a == l || a =~ Regexp.new("#{l}-\w*")}
langs.each do |l|
a = available.find{ |a| a =~ Regexp.new("\\A#{l}\\Z", 'i') ||
a =~ Regexp.new("#{l}-\w*", 'i') }
if a
chosen_lang = a
break
end
end
chosen_lang = "en" if chosen_lang.blank?
$LOG.debug "Chosen locale is #{chosen_lang.inspect}"
return chosen_lang
end
def available_locales
(Dir.glob(File.join(File.dirname(File.expand_path(__FILE__)), "../../locale/[a-z]*")).map{|path| File.basename(path)} << "en").uniq.collect{|l| l.gsub('_','-')}
end

Просмотреть файл

@ -1,7 +1,7 @@
require 'camping/ar'
module CASServer::Models
module Consumable
def consume!
self.consumed = Time.now
@ -15,7 +15,7 @@ module CASServer::Models
module ClassMethods
def cleanup(max_lifetime, max_unconsumed_lifetime)
transaction do
conditions = ["created_on < ? OR (consumed IS NULL AND created_on < ?)",
conditions = ["created_on < ? OR (consumed IS NULL AND created_on < ?)",
Time.now - max_lifetime,
Time.now - max_unconsumed_lifetime]
expired_tickets_count = count(:conditions => conditions)
@ -28,78 +28,78 @@ module CASServer::Models
end
end
end
class Ticket < Base
def to_s
ticket
end
def self.cleanup(max_lifetime)
transaction do
conditions = ["created_on < ?", Time.now - max_lifetime]
expired_tickets_count = count(:conditions => conditions)
$LOG.debug("Destroying #{expired_tickets_count} expired #{self.name.demodulize}"+
"#{'s' if expired_tickets_count > 1}.") if expired_tickets_count > 0
destroy_all(conditions)
end
end
end
class LoginTicket < Ticket
set_table_name 'casserver_lt'
include Consumable
end
class ServiceTicket < Ticket
set_table_name 'casserver_st'
include Consumable
belongs_to :granted_by_tgt,
belongs_to :granted_by_tgt,
:class_name => 'CASServer::Models::TicketGrantingTicket',
:foreign_key => :granted_by_tgt_id
has_one :proxy_granting_ticket,
:foreign_key => :created_by_st_id
def matches_service?(service)
CASServer::CAS.clean_service_url(self.service) ==
CASServer::CAS.clean_service_url(self.service) ==
CASServer::CAS.clean_service_url(service)
end
end
class ProxyTicket < ServiceTicket
belongs_to :granted_by_pgt,
:class_name => 'CASServer::Models::ProxyGrantingTicket',
:foreign_key => :granted_by_pgt_id
end
class TicketGrantingTicket < Ticket
set_table_name 'casserver_tgt'
serialize :extra_attributes
has_many :granted_service_tickets,
has_many :granted_service_tickets,
:class_name => 'CASServer::Models::ServiceTicket',
:foreign_key => :granted_by_tgt_id
end
class ProxyGrantingTicket < Ticket
set_table_name 'casserver_pgt'
belongs_to :service_ticket
has_many :granted_proxy_tickets,
has_many :granted_proxy_tickets,
:class_name => 'CASServer::Models::ProxyTicket',
:foreign_key => :granted_by_pgt_id
end
class Error
attr_reader :code, :message
def initialize(code, message)
@code = code
@message = message
end
def to_s
message
end
@ -109,14 +109,14 @@ module CASServer::Models
def self.up
if ActiveRecord::Base.connection.table_alias_length > 30
$LOG.info("Creating database with long table names...")
create_table :casserver_login_tickets, :force => true do |t|
t.column :ticket, :string, :null => false
t.column :created_on, :timestamp, :null => false
t.column :consumed, :datetime, :null => true
t.column :client_hostname, :string, :null => false
end
create_table :casserver_service_tickets, :force => true do |t|
t.column :ticket, :string, :null => false
t.column :service, :string, :null => false
@ -127,14 +127,14 @@ module CASServer::Models
t.column :type, :string, :null => false
t.column :proxy_granting_ticket_id, :integer, :null => true
end
create_table :casserver_ticket_granting_tickets, :force => true do |t|
t.column :ticket, :string, :null => false
t.column :created_on, :timestamp, :null => false
t.column :client_hostname, :string, :null => false
t.column :username, :string, :null => false
end
create_table :casserver_proxy_granting_tickets, :force => true do |t|
t.column :ticket, :string, :null => false
t.column :created_on, :timestamp, :null => false
@ -144,7 +144,7 @@ module CASServer::Models
end
end
end
def self.down
if ActiveRecord::Base.connection.table_alias_length > 30
drop_table :casserver_proxy_granting_tickets
@ -154,8 +154,8 @@ module CASServer::Models
end
end
end
# Oracle table names cannot exceed 30 chars...
# Oracle table names cannot exceed 30 chars...
# See http://code.google.com/p/rubycas-server/issues/detail?id=15
class ShortenTableNames < V 0.5
def self.up
@ -172,7 +172,7 @@ module CASServer::Models
t.column :consumed, :datetime, :null => true
t.column :client_hostname, :string, :null => false
end
create_table :casserver_st, :force => true do |t|
t.column :ticket, :string, :null => false
t.column :service, :string, :null => false
@ -183,14 +183,14 @@ module CASServer::Models
t.column :type, :string, :null => false
t.column :proxy_granting_ticket_id, :integer, :null => true
end
create_table :casserver_tgt, :force => true do |t|
t.column :ticket, :string, :null => false
t.column :created_on, :timestamp, :null => false
t.column :client_hostname, :string, :null => false
t.column :username, :string, :null => false
end
create_table :casserver_pgt, :force => true do |t|
t.column :ticket, :string, :null => false
t.column :created_on, :timestamp, :null => false
@ -200,7 +200,7 @@ module CASServer::Models
end
end
end
def self.down
if ActiveRecord::Base.connection.table_alias_length > 30
rename_table :casserver_lt, :cassserver_login_tickets
@ -215,17 +215,17 @@ module CASServer::Models
end
end
end
class AddTgtToSt < V 0.7
def self.up
add_column :casserver_st, :tgt_id, :integer, :null => true
end
def self.down
remove_column :casserver_st, :tgt_id, :integer
end
end
class ChangeServiceToText < V 0.71
def self.up
# using change_column to change the column type from :string to :text
@ -235,17 +235,17 @@ module CASServer::Models
say "WARNING: All existing service tickets are being deleted."
add_column :casserver_st, :service, :text
end
def self.down
change_column :casserver_st, :service, :string
end
end
class AddExtraAttributes < V 0.72
def self.up
add_column :casserver_tgt, :extra_attributes, :text
end
def self.down
remove_column :casserver_tgt, :extra_attributes
end

Просмотреть файл

@ -1,50 +1,50 @@
module CASServer
module Postambles
def webrick
require 'webrick/httpserver'
require 'webrick/https'
require 'camping/webrick'
# TODO: verify the certificate's validity
# example of how to do this is here: http://pablotron.org/download/ruri-20050331.rb
cert_path = $CONF.ssl_cert
key_path = $CONF.ssl_key || $CONF.ssl_cert
# look for the key in the ssl_cert if no ssl_key is specified
webrick_options = {:BindAddress => "0.0.0.0", :Port => $CONF.port}
unless cert_path.nil? && key_path.nil?
raise "'#{cert_path}' is not a valid ssl certificate. Your 'ssl_cert' configuration" +
" setting must be a path to a valid ssl certificate file." unless
File.exists? cert_path
raise "'#{key_path}' is not a valid ssl private key. Your 'ssl_key' configuration" +
" setting must be a path to a valid ssl private key file." unless
File.exists? key_path
cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
key = OpenSSL::PKey::RSA.new(File.read(key_path))
webrick_options[:SSLEnable] = true
webrick_options[:SSLVerifyClient] = ::OpenSSL::SSL::VERIFY_NONE
webrick_options[:SSLCertificate] = cert
webrick_options[:SSLPrivateKey] = key
end
begin
s = WEBrick::HTTPServer.new(webrick_options)
rescue Errno::EACCES
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."
exit 2
end
CASServer.create
s.mount "#{$CONF.uri_path}", WEBrick::CampingHandler, CASServer
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"
# This lets Ctrl+C shut down your server
trap(:INT) do
s.shutdown
@ -52,7 +52,7 @@ module CASServer
trap(:TERM) do
s.shutdown
end
if $DAEMONIZE
WEBrick::Daemon.start do
write_pid_file if $PID_FILE
@ -63,33 +63,33 @@ module CASServer
s.start
end
end
def mongrel
require 'rubygems'
require 'mongrel/camping'
if $DAEMONIZE
# check if log and pid are writable before daemonizing, otherwise we won't be able to notify
# the user if we run into trouble later (since once daemonized, we can't write to stdout/stderr)
check_pid_writable if $PID_FILE
check_log_writable
end
CASServer.create
puts "\n** CASServer is starting. Look in '#{$CONF.log[:file]}' for further notices."
settings = {:host => "0.0.0.0", :log_file => $CONF.log[:file], :cwd => $CASSERVER_HOME}
# need to close all IOs before daemonizing
$LOG.close if $DAEMONIZE
begin
config = Mongrel::Configurator.new settings do
daemonize :log_file => $CONF.log[:file], :cwd => $CASSERVER_HOME if $DAEMONIZE
listener :port => $CONF.port do
uri $CONF.uri_path, :handler => Mongrel::Camping::CampingHandler.new(CASServer)
setup_signals
@ -98,12 +98,12 @@ module CASServer
rescue Errno::EADDRINUSE
exit 1
end
config.run
CASServer.init_logger
CASServer.init_db_logger
if $DAEMONIZE && $PID_FILE
write_pid_file
unless File.exists? $PID_FILE
@ -111,7 +111,7 @@ module CASServer
exit 1
end
end
puts "\n** CASServer is running at http://localhost:#{$CONF.port}#{$CONF.uri_path} and logging to '#{$CONF.log[:file]}'"
config.join
@ -119,22 +119,22 @@ module CASServer
puts "\n** CASServer is stopped (#{Time.now})"
end
def fastcgi
require 'camping/fastcgi'
Dir.chdir('/srv/www/camping/casserver/')
CASServer.create
Camping::FastCGI.start(CASServer)
end
def cgi
CASServer.create
puts CASServer.run
end
private
def check_log_writable
log_file = $CONF.log['file']
@ -146,10 +146,10 @@ module CASServer
end
f.close
end
def check_pid_writable
$LOG.debug "Checking if pid file '#{$PID_FILE}' is writable"
begin
begin
f = open($PID_FILE, 'w')
rescue
$stderr.puts "Couldn't write to log at '#{$PID_FILE}' (#{$!})."
@ -157,18 +157,18 @@ module CASServer
end
f.close
end
def write_pid_file
$LOG.debug "Writing pid '#{Process.pid}' to pid file '#{$PID_FILE}'"
open($PID_FILE, "w") { |file| file.write(Process.pid) }
end
def clear_pid_file
if $PID_FILE && File.exists?($PID_FILE)
$LOG.debug "Clearing pid file '#{$PID_FILE}'"
File.unlink $PID_FILE
end
end
end
end

Просмотреть файл

@ -4,19 +4,19 @@ module CASServer
def random_string(max_length = 29)
rg = Crypt::ISAAC.new
max = 4294619050
r = "#{Time.now.to_i}r%X%X%X%X%X%X%X%X" %
[rg.rand(max), rg.rand(max), rg.rand(max), rg.rand(max),
r = "#{Time.now.to_i}r%X%X%X%X%X%X%X%X" %
[rg.rand(max), rg.rand(max), rg.rand(max), rg.rand(max),
rg.rand(max), rg.rand(max), rg.rand(max), rg.rand(max)]
r[0..max_length-1]
end
module_function :random_string
def log_controller_action(controller, params)
$LOG << "\n"
/`(.*)'/.match(caller[1])
method = $~[1]
if params.respond_to? :dup
params2 = params.dup
params2['password'] = '******' if params2['password']
@ -27,4 +27,4 @@ module CASServer
end
module_function :log_controller_action
end
end
end

Просмотреть файл

@ -5,7 +5,7 @@
Markaby::Builder.set(:auto_validation, false)
# disabled XML indentation because it was causing problems with mod_auth_cas
#Markaby::Builder.set(:indent, 2)
#Markaby::Builder.set(:indent, 2)
module CASServer::Views
@ -13,7 +13,7 @@ module CASServer::Views
# wrap as XHTML only when auto_validation is on, otherwise pass right through
if @use_layout
xhtml_strict do
head do
head do
title { "#{organization} #{_(' Central Login')}" }
link(:rel => "stylesheet", :type => "text/css", :href => "/themes/cas.css")
link(:rel => "stylesheet", :type => "text/css", :href => "/themes/#{current_theme}/theme.css")
@ -21,7 +21,7 @@ module CASServer::Views
File.exists?("#{$APP_ROOT}/public/themes/#{current_theme}/favicon.png")
end
body(:onload => "if (document.getElementById('username')) document.getElementById('username').focus()") do
self << yield
self << yield
end
end
else
@ -34,7 +34,7 @@ module CASServer::Views
# The full login page.
def login
@use_layout = true
table(:id => "login-box") do
tr do
td(:colspan => 2) do
@ -62,11 +62,12 @@ module CASServer::Views
end
end
end
# Just the login form.
def login_form
submitbutton = _("Please wait...")
form(:method => "post", :action => @form_action || '/login', :id => "login-form",
:onsubmit => "submitbutton = document.getElementById('login-submit'); submitbutton.value='#{ _("Please wait...") }'; submitbutton.disabled=true; return true;") do
:onsubmit => "submitbutton = document.getElementById('login-submit'); submitbutton.value='#{submitbutton}'; submitbutton.disabled=true; return true;") do
table(:id => "form-layout") do
tr do
td(:id => "username-label-container") do
@ -82,7 +83,7 @@ module CASServer::Views
label(:id => "password-label", :for => "password") { _( "Password" ) }
end
td(:id => "password-container") do
input(:type => "password", :id => "password", :name => "password",
input(:type => "password", :id => "password", :name => "password",
:size => "32", :tabindex => "2", :accesskey => "p", :autocomplete => "off")
end
end
@ -100,11 +101,11 @@ module CASServer::Views
end
end
end
# 2.3.2
def logout
@use_layout = true
table(:id => "login-box") do
tr do
td(:colspan => 2) do
@ -128,7 +129,7 @@ module CASServer::Views
end
end
end
# 2.4.2
# CAS 1.0 validate response.
def validate
@ -138,7 +139,7 @@ module CASServer::Views
text "no\n\n"
end
end
# 2.5.2
# CAS 2.0 service validate response.
def service_validate
@ -160,7 +161,7 @@ module CASServer::Views
end
end
end
# 2.6.2
# CAS 2.0 proxy validate response.
def proxy_validate
@ -189,7 +190,7 @@ module CASServer::Views
end
end
end
# 2.7.2
# CAS 2.0 proxy request response.
def proxy
@ -205,31 +206,31 @@ module CASServer::Views
end
end
end
def configure
end
protected
def themes_dir
File.dirname(File.expand_path(__FILE__))+'../themes'
end
module_function :themes_dir
def current_theme
$CONF.theme || "simple"
end
module_function :current_theme
def organization
$CONF.organization || ""
end
module_function :organization
def infoline
$CONF.infoline || ""
end
module_function :infoline
def serialize_extra_attribute(value)
if value.kind_of?(String) || value.kind_of?(Numeric)
value

Просмотреть файл

@ -1 +1 @@
require File.dirname(__FILE__)+'/casserver'
require File.dirname(__FILE__)+'/casserver'

Просмотреть файл

@ -1 +1 @@
require File.dirname(__FILE__)+'/../casserver/version.rb'
require File.dirname(__FILE__)+'/../casserver/version.rb'

Просмотреть файл

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-05-06 18:16-0400\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2008-11-12 12:49-0500\n"
"Last-Translator: Matt Zukowski <mzukowski@urbacon.net>\n"
"Language-Team: German\n"
@ -62,7 +62,7 @@ msgstr ""
"Der Server kann diese Gateway-Anfrage nicht erfüllen, da keine Service-"
"Parameter übergeben wurden."
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:195
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:179
msgid ""
"The target service your browser supplied appears to be invalid. Please "
"contact your system administrator for help."
@ -79,41 +79,49 @@ msgstr ""
"Der CAS-Login-URI konnte nicht erraten werden. Bitte ergänzen Sie Ihre "
"Anfrage um einen submitToURI Parameter."
#: lib/casserver/controllers.rb:184
#: lib/casserver/controllers.rb:168
msgid "You have successfully logged in."
msgstr ""
"Sie haben sich erfolgreich am Central Authentication Service angemeldet."
#: lib/casserver/controllers.rb:200
#: lib/casserver/controllers.rb:184
msgid "Incorrect username or password."
msgstr "Falscher Benutzername oder Passwort."
#: lib/casserver/controllers.rb:257
#: lib/casserver/controllers.rb:267
msgid "You have successfully logged out."
msgstr ""
"Sie haben sich erfolgreich vom Central Authentication Service abgemeldet."
#: lib/casserver/controllers.rb:260
#: lib/casserver/controllers.rb:269
msgid " Please click on the following link to continue:"
msgstr " Bitte klicken Sie auf den folgenden Link, um fortzufahren:"
#: lib/casserver/controllers.rb:410
#: lib/casserver/controllers.rb:419
msgid "To generate a login ticket, you must make a POST request."
msgstr ""
"Für die Generierung eines Login-Tickets, ist eine POST-Anfrage erforderlich."
#: lib/casserver/views.rb:43 lib/casserver/views.rb:113
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr " Zentrales Login"
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr ""
#: lib/casserver/views.rb:74
msgid "Username"
msgstr "Benutzername"
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr "Passwort"
#: lib/casserver/views.rb:94
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr ""
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr "ANMELDEN"

Просмотреть файл

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-05-06 18:16-0400\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2008-11-12 12:30-0500\n"
"Last-Translator: Matt Zukowski <mzukowski@urbacon.net>\n"
"Language-Team: Spanish\n"
@ -61,7 +61,7 @@ msgstr ""
"El servidor no puede cumplir con esta petición, porque no fue parámetro de "
"servicio prestado."
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:195
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:179
msgid ""
"The target service your browser supplied appears to be invalid. Please "
"contact your system administrator for help."
@ -78,38 +78,46 @@ msgstr ""
"No podía adivinar el URI de acceso CAS. Suministro submitToURI un parámetro "
"con su solicitud."
#: lib/casserver/controllers.rb:184
#: lib/casserver/controllers.rb:168
msgid "You have successfully logged in."
msgstr "Inicio de sesión satisfactorio."
#: lib/casserver/controllers.rb:200
#: lib/casserver/controllers.rb:184
msgid "Incorrect username or password."
msgstr "Incorrecto nombre de usuario o contraseña."
#: lib/casserver/controllers.rb:257
#: lib/casserver/controllers.rb:267
msgid "You have successfully logged out."
msgstr "Cierre de sesión satisfactorio."
#: lib/casserver/controllers.rb:260
#: lib/casserver/controllers.rb:269
msgid " Please click on the following link to continue:"
msgstr " Por favor, haga clic en el vínculo siguiente para continuar:"
#: lib/casserver/controllers.rb:410
#: lib/casserver/controllers.rb:419
msgid "To generate a login ticket, you must make a POST request."
msgstr "Para generar un ticket de acceso, usted debe hacer una petición POST."
#: lib/casserver/views.rb:43 lib/casserver/views.rb:113
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr " Servicio de Autenticación Central"
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr ""
#: lib/casserver/views.rb:74
msgid "Username"
msgstr "Usuario"
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr "Contraseña"
#: lib/casserver/views.rb:94
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr ""
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr "INICIAR SESIÓN"

Просмотреть файл

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-05-06 18:16-0400\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2008-11-12 11:53-0500\n"
"Last-Translator: Matt Zukowski <mzukowski@urbacon.net>\n"
"Language-Team: French\n"
@ -61,7 +61,7 @@ msgstr ""
"Le serveur ne peut pas répondre à cette demande (pas de 'service' paramètre "
"a été donné)."
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:195
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:179
msgid ""
"The target service your browser supplied appears to be invalid. Please "
"contact your system administrator for help."
@ -77,40 +77,48 @@ msgstr ""
"Impossible de deviner le CAS de connexion URI. S'il vous plaît fournir une "
"submitToURI paramètre à votre demande."
#: lib/casserver/controllers.rb:184
#: lib/casserver/controllers.rb:168
msgid "You have successfully logged in."
msgstr ""
"Vous vous êtes authentifié(e) auprès du Service Central d'Authentification."
#: lib/casserver/controllers.rb:200
#: lib/casserver/controllers.rb:184
msgid "Incorrect username or password."
msgstr "Les informations transmises n'ont pas permis de vous authentifier"
#: lib/casserver/controllers.rb:257
#: lib/casserver/controllers.rb:267
msgid "You have successfully logged out."
msgstr "Vous vous êtes déconnecté(e) du Service Central d'Authentification."
#: lib/casserver/controllers.rb:260
#: lib/casserver/controllers.rb:269
msgid " Please click on the following link to continue:"
msgstr " S'il vous plaît cliquer sur le lien suivant pour continuer:"
#: lib/casserver/controllers.rb:410
#: lib/casserver/controllers.rb:419
msgid "To generate a login ticket, you must make a POST request."
msgstr ""
"Pour générer un ticket de connexion, vous devez faire une requête POST."
#: lib/casserver/views.rb:43 lib/casserver/views.rb:113
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr " Service Central d'Authentification."
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr ""
#: lib/casserver/views.rb:74
msgid "Username"
msgstr "Identifiant"
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr "Mot de passe"
#: lib/casserver/views.rb:94
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr ""
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr "SE CONNECTER"

Просмотреть файл

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-05-06 18:16-0400\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2008-11-12 13:04-0500\n"
"Last-Translator: Matt Zukowski <mzukowski@urbacon.net>\n"
"Language-Team: Japanese\n"
@ -65,7 +65,7 @@ msgstr ""
"サービスパラメーターが指定されていないので、サーバーはゲートウェイリクエスト"
"を満たす事ができません。"
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:195
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:179
msgid ""
"The target service your browser supplied appears to be invalid. Please "
"contact your system administrator for help."
@ -81,38 +81,46 @@ msgstr ""
"CASのURIを推測することができませんでした。リクエストにsubmitToURIパラメータを"
"指定してください。"
#: lib/casserver/controllers.rb:184
#: lib/casserver/controllers.rb:168
msgid "You have successfully logged in."
msgstr "ログインしました"
#: lib/casserver/controllers.rb:200
#: lib/casserver/controllers.rb:184
msgid "Incorrect username or password."
msgstr "ユーザー名またはパスワードが間違っています"
#: lib/casserver/controllers.rb:257
#: lib/casserver/controllers.rb:267
msgid "You have successfully logged out."
msgstr "ログアウトしました。"
#: lib/casserver/controllers.rb:260
#: lib/casserver/controllers.rb:269
msgid " Please click on the following link to continue:"
msgstr " 継続するには、以下のリンクをクリックしてください:"
#: lib/casserver/controllers.rb:410
#: lib/casserver/controllers.rb:419
msgid "To generate a login ticket, you must make a POST request."
msgstr "ログインチケットを発行するには、POSTリクエストを送る必要があります。"
#: lib/casserver/views.rb:43 lib/casserver/views.rb:113
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr " 統合ログイン"
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr ""
#: lib/casserver/views.rb:74
msgid "Username"
msgstr "ユーザー名"
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr "パスワード"
#: lib/casserver/views.rb:94
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr ""
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr "ログイン"

Просмотреть файл

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-05-06 18:16-0400\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2008-11-12 11:03-0500\n"
"Last-Translator: Matt Zukowski <mzukowski@urbacon.net>\n"
"Language-Team: Polish\n"
@ -62,7 +62,7 @@ msgstr ""
"Serwer nie może spełnić tego żądania bramowego, ponieważ nie został podany "
"parametr usługi."
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:195
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:179
msgid ""
"The target service your browser supplied appears to be invalid. Please "
"contact your system administrator for help."
@ -78,38 +78,46 @@ msgstr ""
"Nie można odgadnąć URI do logowania do CAS. Proszę dostarczyć parametr "
"submitToURI."
#: lib/casserver/controllers.rb:184
#: lib/casserver/controllers.rb:168
msgid "You have successfully logged in."
msgstr "Jesteś zalogowany."
#: lib/casserver/controllers.rb:200
#: lib/casserver/controllers.rb:184
msgid "Incorrect username or password."
msgstr "Niepoprawny użytkownik lub hasło."
#: lib/casserver/controllers.rb:257
#: lib/casserver/controllers.rb:267
msgid "You have successfully logged out."
msgstr "Jesteś wylogowany."
#: lib/casserver/controllers.rb:260
#: lib/casserver/controllers.rb:269
msgid " Please click on the following link to continue:"
msgstr " Proszę kliknąć na poniższy link, aby kontynuować:"
#: lib/casserver/controllers.rb:410
#: lib/casserver/controllers.rb:419
msgid "To generate a login ticket, you must make a POST request."
msgstr "Aby wygenerować login bilet, musisz złożyć żądanie POST."
#: lib/casserver/views.rb:43 lib/casserver/views.rb:113
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr " Centralna Usługa Uwierzytelniania"
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr ""
#: lib/casserver/views.rb:74
msgid "Username"
msgstr "Użytkownik"
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr "Hasło"
#: lib/casserver/views.rb:94
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr ""
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr "ZALOGUJ"

Просмотреть файл

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-05-06 18:16-0400\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2009-03-17 20:55+0200\n"
"Last-Translator: Kivanio Barbosa <kivanio@gmail.com>\n"
"Language-Team: Brazil\n"
@ -61,7 +61,7 @@ msgstr ""
"O servidor não pode completar a solicitação porque não foi enviado o "
"paramêtro do serviço."
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:195
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:179
msgid ""
"The target service your browser supplied appears to be invalid. Please "
"contact your system administrator for help."
@ -77,39 +77,47 @@ msgstr ""
"Não encontramos a URI de acesso ao CAS. Por favor, informe corretamente no "
"submitToURI com sua solicitação."
#: lib/casserver/controllers.rb:184
#: lib/casserver/controllers.rb:168
msgid "You have successfully logged in."
msgstr "Login efetuado com sucesso."
#: lib/casserver/controllers.rb:200
#: lib/casserver/controllers.rb:184
msgid "Incorrect username or password."
msgstr "Usuário ou Senha está incorreto."
#: lib/casserver/controllers.rb:257
#: lib/casserver/controllers.rb:267
msgid "You have successfully logged out."
msgstr "Você saiu do sistema com sucesso."
#: lib/casserver/controllers.rb:260
#: lib/casserver/controllers.rb:269
msgid " Please click on the following link to continue:"
msgstr " Por favor, clique no seguinte link para continuar:"
#: lib/casserver/controllers.rb:410
#: lib/casserver/controllers.rb:419
msgid "To generate a login ticket, you must make a POST request."
msgstr ""
"Para gerar um ticket de acceso, você deve fazer uma requisição via POST."
#: lib/casserver/views.rb:43 lib/casserver/views.rb:113
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr " Central de Autenticação"
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr ""
#: lib/casserver/views.rb:74
msgid "Username"
msgstr "Usuário"
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr "Senha"
#: lib/casserver/views.rb:94
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr ""
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr "ENTRAR"

Просмотреть файл

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-05-06 18:16-0400\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2008-11-04 12:32+0200\n"
"Last-Translator: Antono Vasiljev <antono.vasiljev@gmail.com>\n"
"Language-Team: Russian <ru@li.org>\n"
@ -57,7 +57,7 @@ msgstr ""
"Этот сервер не может выполнить этот запрос, поскольку не были указаны "
"праметры сервиса."
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:195
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:179
msgid ""
"The target service your browser supplied appears to be invalid. Please "
"contact your system administrator for help."
@ -73,38 +73,46 @@ msgstr ""
"Не возможно угадать адрес входа на CAS. Пожалуйста, передайте с запросом "
"параметр submitToURI."
#: lib/casserver/controllers.rb:184
#: lib/casserver/controllers.rb:168
msgid "You have successfully logged in."
msgstr "Вы успешно вошли."
#: lib/casserver/controllers.rb:200
#: lib/casserver/controllers.rb:184
msgid "Incorrect username or password."
msgstr "Неверное имя пользователя или пароль."
#: lib/casserver/controllers.rb:257
#: lib/casserver/controllers.rb:267
msgid "You have successfully logged out."
msgstr "Вы успешно вышли."
#: lib/casserver/controllers.rb:260
#: lib/casserver/controllers.rb:269
msgid " Please click on the following link to continue:"
msgstr " Перейдите по ссылке чтобы продолжить: "
#: lib/casserver/controllers.rb:410
#: lib/casserver/controllers.rb:419
msgid "To generate a login ticket, you must make a POST request."
msgstr "Чтобы сгенерировать входной билет вы должны делать POST запрос."
#: lib/casserver/views.rb:43 lib/casserver/views.rb:113
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr " Центральный вход"
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr ""
#: lib/casserver/views.rb:74
msgid "Username"
msgstr "Логин"
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr "Пароль"
#: lib/casserver/views.rb:94
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr ""
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr "Войти"

Просмотреть файл

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-05-06 18:16-0400\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2008-10-29 20:55+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -55,7 +55,7 @@ msgid ""
"was given."
msgstr ""
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:195
#: lib/casserver/controllers.rb:59 lib/casserver/controllers.rb:179
msgid ""
"The target service your browser supplied appears to be invalid. Please "
"contact your system administrator for help."
@ -67,38 +67,46 @@ msgid ""
"with your request."
msgstr ""
#: lib/casserver/controllers.rb:184
#: lib/casserver/controllers.rb:168
msgid "You have successfully logged in."
msgstr ""
#: lib/casserver/controllers.rb:200
#: lib/casserver/controllers.rb:184
msgid "Incorrect username or password."
msgstr ""
#: lib/casserver/controllers.rb:257
#: lib/casserver/controllers.rb:267
msgid "You have successfully logged out."
msgstr ""
#: lib/casserver/controllers.rb:260
#: lib/casserver/controllers.rb:269
msgid " Please click on the following link to continue:"
msgstr ""
#: lib/casserver/controllers.rb:410
#: lib/casserver/controllers.rb:419
msgid "To generate a login ticket, you must make a POST request."
msgstr ""
#: lib/casserver/views.rb:43 lib/casserver/views.rb:113
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr ""
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr ""
#: lib/casserver/views.rb:74
msgid "Username"
msgstr ""
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr ""
#: lib/casserver/views.rb:94
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr ""
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr ""

Просмотреть файл

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: rubycas-server \n"
"POT-Creation-Date: 2009-09-29 16:29+0800\n"
"POT-Creation-Date: 2009-09-29 17:04+0800\n"
"PO-Revision-Date: 2009-03-17 20:55+0200\n"
"Last-Translator: Lin Jen-Shin <godfat@godfat.org>\n"
"Language-Team: Traditional Chinese\n"
@ -87,23 +87,27 @@ msgstr " 請點以下的連結繼續"
msgid "To generate a login ticket, you must make a POST request."
msgstr "你必須使用 POST 來產生登入憑証"
#: lib/casserver/views.rb:43 lib/casserver/views.rb:119
#: lib/casserver/views.rb:43 lib/casserver/views.rb:120
msgid " Central Login"
msgstr " 整合登入"
#: lib/casserver/views.rb:73
#: lib/casserver/views.rb:68
msgid "Please wait..."
msgstr "請稍候..."
#: lib/casserver/views.rb:74
msgid "Username"
msgstr "帳號"
#: lib/casserver/views.rb:82
#: lib/casserver/views.rb:83
msgid "Password"
msgstr "密碼"
#: lib/casserver/views.rb:91
#: lib/casserver/views.rb:92
msgid "Remeber me on this computer"
msgstr "在這台電腦上記住我"
#: lib/casserver/views.rb:100
#: lib/casserver/views.rb:101
msgid "LOGIN"
msgstr "登入"

Просмотреть файл

@ -1,5 +1,5 @@
* {
font-family: Verdana, sans-serif;
font-family: Verdana, sans-serif;
}
body {
@ -7,115 +7,115 @@ body {
}
label {
font-weight: bold;
font-size: 9px;
font-weight: bold;
font-size: 9px;
}
input {
font-weight: normal;
font-size: 12px;
font-weight: normal;
font-size: 12px;
}
input.button {
/*font-weight: bold;*/
font-size: 10px;
/*font-weight: bold;*/
font-size: 10px;
}
#login-box {
margin: 0 auto;
width: 350px;
top: 130px;
position: relative;
margin: 0 auto;
width: 350px;
top: 130px;
position: relative;
}
#headline-container {
text-align: right;
border-bottom: 1px solid #899989;
font-family: Tahoma, Verdana, sans-serif;
font-size: 22px;
margin-right: 0px;
padding-right: 7px;
margin-left: 10px;
letter-spacing: -0.25px;
text-align: right;
border-bottom: 1px solid #899989;
font-family: Tahoma, Verdana, sans-serif;
font-size: 22px;
margin-right: 0px;
padding-right: 7px;
margin-left: 10px;
letter-spacing: -0.25px;
}
#logo-container {
vertical-align: top;
vertical-align: top;
}
#logo {
}
#login-form-container {
vertical-align: top;
vertical-align: top;
}
#username,
#password {
width: 10em;
width: 10em;
}
#login-form {
padding: 20px;
padding: 20px;
}
#form-layout {
position: relative;
top: 6px;
width: 100%;
position: relative;
top: 6px;
width: 100%;
}
#form-layout td {
text-align: center;
padding-bottom: 8px;
text-align: center;
padding-bottom: 8px;
}
#form-layout td#submit-container {
text-align: right;
padding-right: 10px;
text-align: right;
padding-right: 10px;
}
#infoline {
font-size: 9px;
font-size: 9px;
}
#messagebox-container {
padding-left: 11px;
padding-right: 16px;
padding-left: 11px;
padding-right: 16px;
}
div.messagebox {
font-size: 12px;
padding: 5px;
padding-left: 55px;
text-align: center;
width: 70%;
min-height: 34px;
vertical-align: middle;
font-size: 12px;
padding: 5px;
padding-left: 55px;
text-align: center;
width: 70%;
min-height: 34px;
vertical-align: middle;
}
div.mistake {
color: #d00;
background-image: url(warning.png);
background-repeat: no-repeat;
background-position: 10px 5px;
font-weight: bold;
color: #d00;
background-image: url(warning.png);
background-repeat: no-repeat;
background-position: 10px 5px;
font-weight: bold;
}
div.confirmation {
color: #280;
background-image: url(ok.png);
background-repeat: no-repeat;
background-position: 10px 5px;
font-weight: bold;
color: #280;
background-image: url(ok.png);
background-repeat: no-repeat;
background-position: 10px 5px;
font-weight: bold;
}
div.notice {
color: #04c;
background-image: url(notice.png);
background-repeat: no-repeat;
background-position: 10px 5px;
font-weight: bold;
}
color: #04c;
background-image: url(notice.png);
background-repeat: no-repeat;
background-position: 10px 5px;
font-weight: bold;
}

Просмотреть файл

@ -1,28 +1,28 @@
body {
background-image: url(bg.png);
background-image: url(bg.png);
}
#headline-container {
margin-bottom: 5px;
margin-bottom: 5px;
}
#login-box {
margin: 0 auto;
width: 450px;
top: 110px;
position: relative;
margin: 0 auto;
width: 450px;
top: 110px;
position: relative;
}
#login-form {
background-color: #fff;
border: 1px #aaa solid;
background-color: #fff;
border: 1px #aaa solid;
}
#logo-container {
vertical-align: middle;
vertical-align: middle;
}
#logo {
width: 128px;
height: 128px;
}
}

Просмотреть файл

@ -1,21 +1,21 @@
body {
background-image: url(bg.png);
background-image: url(bg.png);
}
label {
color: #5c6156;
color: #5c6156;
}
#login-form {
background-repeat: no-repeat;
background-image: url(login_box_bg.png);
height: 175px;
width: 210px;
padding: 20px;
background-repeat: no-repeat;
background-image: url(login_box_bg.png);
height: 175px;
width: 210px;
padding: 20px;
}
#logo-container {
vertical-align: top;
vertical-align: top;
}
#logo {
@ -24,10 +24,10 @@ label {
}
#infoline {
color: #5c6156;
font-size: 8px;
color: #5c6156;
font-size: 8px;
}
#headline-container {
margin-right: 15px;
}
margin-right: 15px;
}

Просмотреть файл

@ -659,7 +659,7 @@ module FileOperations
def ruby(*args)
command config('rubyprog'), *args
end
def make(task = nil)
command(*[config('makeprog'), task].compact)
end
@ -722,7 +722,7 @@ module HookScriptAPI
def srcdirectory?(path)
File.dir?(srcfile(path))
end
def srcfile?(path)
File.file?(srcfile(path))
end
@ -826,7 +826,7 @@ class ToplevelInstaller
__send__ "exec_#{task}"
end
end
def run_metaconfigs
@config.load_script "#{@ardir}/metaconfig"
end
@ -1404,7 +1404,7 @@ class Installer
end
# picked up many entries from cvs-1.11.1/src/ignore.c
JUNK_FILES = %w(
JUNK_FILES = %w(
core RCSLOG tags TAGS .make.state
.nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
*~ *.old *.bak *.BAK *.orig *.rej _$* *$

Просмотреть файл

@ -31,4 +31,4 @@ namespace :manifest do
task :refresh do
`rake check_manifest | patch -p0 > Manifest.txt`
end
end
end

Просмотреть файл

@ -7,5 +7,5 @@ end
desc 'Creates mo files from po files and puts them to locale dir'
task :mo do
require 'gettext/utils'
GetText.create_mofiles(true, "po", "locale")
GetText.create_mofiles(true, "po", "locale")
end

6
vendor/isaac_0.9.1/TODO поставляемый
Просмотреть файл

@ -1,3 +1,3 @@
* Add a C version of the ISAAC algorithm and make it possible to install
the pure Ruby version and/or a version using a C extension for better
performance.
* Add a C version of the ISAAC algorithm and make it possible to install
the pure Ruby version and/or a version using a C extension for better
performance.

302
vendor/isaac_0.9.1/crypt/ISAAC.rb поставляемый
Просмотреть файл

@ -1,171 +1,171 @@
module Crypt
# ISAAC is a fast, strong random number generator. Details on the
# algorithm can be found here: http://burtleburtle.net/bob/rand/isaac.html
# This provides a consistent and capable algorithm for producing
# independent streams of quality random numbers.
# ISAAC is a fast, strong random number generator. Details on the
# algorithm can be found here: http://burtleburtle.net/bob/rand/isaac.html
# This provides a consistent and capable algorithm for producing
# independent streams of quality random numbers.
class ISAAC
class ISAAC
attr_accessor :randrsl, :randcnt
attr_accessor :mm, :aa, :bb, :cc
attr_accessor :randrsl, :randcnt
attr_accessor :mm, :aa, :bb, :cc
# When a Crypt::ISAAC object is created, it needs to be seeded for
# random number generation. If the system has a /dev/urandom file,
# that will be used to do the seeding by default. If false is explictly
# passed when creating the object, it will instead use /dev/random to
# generate its seeds. Be warned that this may make for SLOW
# initialization.
# If the requested source (/dev/urandom or /dev/random) do not exist,
# the system will fall back to a simplistic initialization mechanism
# using the builtin Mersenne Twister PRNG.
# When a Crypt::ISAAC object is created, it needs to be seeded for
# random number generation. If the system has a /dev/urandom file,
# that will be used to do the seeding by default. If false is explictly
# passed when creating the object, it will instead use /dev/random to
# generate its seeds. Be warned that this may make for SLOW
# initialization.
# If the requested source (/dev/urandom or /dev/random) do not exist,
# the system will fall back to a simplistic initialization mechanism
# using the builtin Mersenne Twister PRNG.
def initialize(noblock = true)
@mm = []
@randrsl = []
# Best initialization of the generator would be by pulling
# numbers from /dev/random.
rnd_source = noblock ? '/dev/urandom' : '/dev/random'
if (FileTest.exist? rnd_source)
File.open(rnd_source,'r') do |r|
256.times do |t|
z = r.read(4)
x = z.unpack('V')[0]
@randrsl[t] = x
end
end
else
# If urandom isn't available, the standard Ruby PRNG makes an
# adequate fallback.
256.times do |t|
@randrsl[t] = Kernel.rand(4294967295)
end
end
randinit(true)
nil
end
def initialize(noblock = true)
@mm = []
@randrsl = []
# Best initialization of the generator would be by pulling
# numbers from /dev/random.
rnd_source = noblock ? '/dev/urandom' : '/dev/random'
if (FileTest.exist? rnd_source)
File.open(rnd_source,'r') do |r|
256.times do |t|
z = r.read(4)
x = z.unpack('V')[0]
@randrsl[t] = x
end
end
else
# If urandom isn't available, the standard Ruby PRNG makes an
# adequate fallback.
256.times do |t|
@randrsl[t] = Kernel.rand(4294967295)
end
end
randinit(true)
nil
end
# Works just like the standard rand() function. If called with an
# integer argument, rand() will return positive random number in
# the range of 0 to (argument - 1). If called without an integer
# argument, rand() returns a positive floating point number less than 1.
def rand(*num)
if (@randcnt == 1)
isaac
@randcnt = 256
end
@randcnt -= 1
if num[0].to_i > 0
@randrsl[@randcnt].modulo(num[0])
else
".#{@randrsl[@randcnt]}".to_f
end
end
# Works just like the standard rand() function. If called with an
# integer argument, rand() will return positive random number in
# the range of 0 to (argument - 1). If called without an integer
# argument, rand() returns a positive floating point number less than 1.
def isaac
i = 0
x = 0
y = 0
def rand(*num)
if (@randcnt == 1)
isaac
@randcnt = 256
end
@randcnt -= 1
if num[0].to_i > 0
@randrsl[@randcnt].modulo(num[0])
else
".#{@randrsl[@randcnt]}".to_f
end
end
@cc += 1
@bb += @cc
@bb & 0xffffffff
def isaac
i = 0
x = 0
y = 0
while (i < 256) do
x = @mm[i]
@aa = (@mm[(i + 128) & 255] + (@aa^(@aa << 13)) ) & 0xffffffff
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
i += 1
@cc += 1
@bb += @cc
@bb & 0xffffffff
x = @mm[i]
@aa = (@mm[(i+128)&255] + (@aa^(0x03ffffff & (@aa >> 6))) ) & 0xffffffff
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
i += 1
while (i < 256) do
x = @mm[i]
@aa = (@mm[(i + 128) & 255] + (@aa^(@aa << 13)) ) & 0xffffffff
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
i += 1
x = @mm[i]
@aa = (@mm[(i + 128)&255] + (@aa^(@aa << 2)) ) & 0xffffffff
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
i += 1
x = @mm[i]
@aa = (@mm[(i+128)&255] + (@aa^(0x03ffffff & (@aa >> 6))) ) & 0xffffffff
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
i += 1
x = @mm[i]
@aa = (@mm[(i+128)&255] + (@aa^(0x0000ffff & (@aa >> 16))) ) & 0xffffffff
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
i += 1
end
end
x = @mm[i]
@aa = (@mm[(i + 128)&255] + (@aa^(@aa << 2)) ) & 0xffffffff
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
i += 1
def randinit(flag)
i = 0
a = 0
b = 0
c = 0
d = 0
e = 0
f = 0
g = 0
@aa = @bb = @cc = 0
a = b = c = d = e = f = g = h = 0x9e3779b9
x = @mm[i]
@aa = (@mm[(i+128)&255] + (@aa^(0x0000ffff & (@aa >> 16))) ) & 0xffffffff
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
i += 1
end
end
while (i < 4) do
a ^= b<<1; d += a; b += c
b ^= 0x3fffffff & (c>>2); e += b; c += d
c ^= d << 8; f += c; d += e
d ^= 0x0000ffff & (e >> 16); g += d; e += f
e ^= f << 10; h += e; f += g
f ^= 0x0fffffff & (g >> 4); a += f; g += h
g ^= h << 8; b += g; h += a
h ^= 0x007fffff & (a >> 9); c += h; a += b
i += 1
end
def randinit(flag)
i = 0
a = 0
b = 0
c = 0
d = 0
e = 0
f = 0
g = 0
@aa = @bb = @cc = 0
a = b = c = d = e = f = g = h = 0x9e3779b9
i = 0
while (i < 256) do
if (flag)
a+=@randrsl[i ].to_i; b+=@randrsl[i+1].to_i;
c+=@randrsl[i+2]; d+=@randrsl[i+3];
e+=@randrsl[i+4]; f+=@randrsl[i+5];
g+=@randrsl[i+6]; h+=@randrsl[i+7];
end
while (i < 4) do
a ^= b<<1; d += a; b += c
b ^= 0x3fffffff & (c>>2); e += b; c += d
c ^= d << 8; f += c; d += e
d ^= 0x0000ffff & (e >> 16); g += d; e += f
e ^= f << 10; h += e; f += g
f ^= 0x0fffffff & (g >> 4); a += f; g += h
g ^= h << 8; b += g; h += a
h ^= 0x007fffff & (a >> 9); c += h; a += b
i += 1
end
a^=b<<11; d+=a; b+=c;
b^=0x3fffffff & (c>>2); e+=b; c+=d;
c^=d<<8; f+=c; d+=e;
d^=0x0000ffff & (e>>16); g+=d; e+=f;
e^=f<<10; h+=e; f+=g;
f^=0x0fffffff & (g>>4); a+=f; g+=h;
g^=h<<8; b+=g; h+=a;
h^=0x007fffff & (a>>9); c+=h; a+=b;
@mm[i]=a;@mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
@mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
i += 8
end
i = 0
while (i < 256) do
if (flag)
a+=@randrsl[i ].to_i; b+=@randrsl[i+1].to_i;
c+=@randrsl[i+2]; d+=@randrsl[i+3];
e+=@randrsl[i+4]; f+=@randrsl[i+5];
g+=@randrsl[i+6]; h+=@randrsl[i+7];
end
if flag
i = 0
while (i < 256)
a+=@mm[i ]; b+=@mm[i+1]; c+=@mm[i+2]; d+=@mm[i+3];
e+=@mm[i+4]; f+=@mm[i+5]; g+=@mm[i+6]; h+=@mm[i+7];
a^=b<<11; d+=a; b+=c;
b^=0x3fffffff & (c>>2); e+=b; c+=d;
c^=d<<8; f+=c; d+=e;
d^=0x0000ffff & (e>>16); g+=d; e+=f;
e^=f<<10; h+=e; f+=g;
f^=0x0fffffff & (g>>4); a+=f; g+=h;
g^=h<<8; b+=g; h+=a;
h^=0x007fffff & (a>>9); c+=h; a+=b;
@mm[i ]=a; @mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
@mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
i += 8
end
end
a^=b<<11; d+=a; b+=c;
b^=0x3fffffff & (c>>2); e+=b; c+=d;
c^=d<<8; f+=c; d+=e;
d^=0x0000ffff & (e>>16); g+=d; e+=f;
e^=f<<10; h+=e; f+=g;
f^=0x0fffffff & (g>>4); a+=f; g+=h;
g^=h<<8; b+=g; h+=a;
h^=0x007fffff & (a>>9); c+=h; a+=b;
@mm[i]=a;@mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
@mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
i += 8
end
isaac()
@randcnt=256; # /* prepare to use the first set of results */
end
end
if flag
i = 0
while (i < 256)
a+=@mm[i ]; b+=@mm[i+1]; c+=@mm[i+2]; d+=@mm[i+3];
e+=@mm[i+4]; f+=@mm[i+5]; g+=@mm[i+6]; h+=@mm[i+7];
a^=b<<11; d+=a; b+=c;
b^=0x3fffffff & (c>>2); e+=b; c+=d;
c^=d<<8; f+=c; d+=e;
d^=0x0000ffff & (e>>16); g+=d; e+=f;
e^=f<<10; h+=e; f+=g;
f^=0x0fffffff & (g>>4); a+=f; g+=h;
g^=h<<8; b+=g; h+=a;
h^=0x007fffff & (a>>9); c+=h; a+=b;
@mm[i ]=a; @mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
@mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
i += 8
end
end
isaac()
@randcnt=256; # /* prepare to use the first set of results */
end
end
end

32
vendor/isaac_0.9.1/setup.rb поставляемый
Просмотреть файл

@ -22,9 +22,9 @@ KINDS = [
#{{{ list of files to be ignored stolen from setup.rb
mapping = { '.' => '\.', '$' => '\$', '#' => '\#', '*' => '.*' }
ignore_files = %w[core RCSLOG tags TAGS .make.state .nse_depinfo
ignore_files = %w[core RCSLOG tags TAGS .make.state .nse_depinfo
#* .#* cvslog.* ,* .del-* *.olb *~ *.old *.bak *.BAK *.orig *.rej _$* *$
*.org *.in .* ]
*.org *.in .* ]
#end of robbery
IGNORE_FILES = ignore_files.map do |x|
Regexp.new('\A' + x.gsub(/[\.\$\#\*]/){|c| mapping[c]} + '\z')
@ -96,7 +96,7 @@ end
module Actions
class InstallFile
attr_reader :source, :destination, :mode
@ -119,7 +119,7 @@ module Actions
end
def eql?(other)
self.class == other.class &&
self.class == other.class &&
@source == other.source &&
@destination == other.destination &&
@mode == other.mode
@ -146,7 +146,7 @@ module Actions
end
def <=>(other)
FULL_ORDER[self, other] || self.directory <=> other.directory
FULL_ORDER[self, other] || self.directory <=> other.directory
end
end
@ -254,17 +254,17 @@ class PackageSpecification_1_0
def self.declare_file_type(args, &handle_arg)
str_arr_p = lambda{|x| Array === x && x.all?{|y| String === y}}
# strict type checking --- we don't want this to be extended arbitrarily
unless args.size == 1 && Hash === args.first &&
unless args.size == 1 && Hash === args.first &&
args.first.all?{|f,r| [Proc, String, NilClass].include?(r.class) &&
(String === f || str_arr_p[f])} or
args.all?{|x| String === x || str_arr_p[x]}
raise SpecificationError,
raise SpecificationError,
"Unspecified semantics for the given arguments: #{args.inspect}"
end
if args.size == 1 && Hash === args.first
if args.size == 1 && Hash === args.first
args.first.to_a.each do |file, rename_info|
if Array === file
# ignoring boring files
@ -284,7 +284,7 @@ class PackageSpecification_1_0
end
end
end
#{{{ define the file tagging methods
KINDS.each { |kind|
define_method(kind) { |*args| # if this were 1.9 we could also take a block
@ -330,7 +330,7 @@ class PackageSpecification_1_0
target, options = @translate[kind][replaced_path]
options ||= TRANSLATE_DEFAULT_OPTIONS
if target && (replaced_path == dir || options[:inherit])
dir = (target != '' ? File.join(target, *kept_dir_parts) :
dir = (target != '' ? File.join(target, *kept_dir_parts) :
File.join(*kept_dir_parts))
break
end
@ -339,7 +339,7 @@ class PackageSpecification_1_0
end
dir
end
def add_file(kind, filename, new_filename_info, &callback)
#TODO: refactor!!!
if File.directory? filename #XXX setup.rb and rpa-base defined File.dir?
@ -423,7 +423,7 @@ class PackageSpecification_1_0
unless options.noop
t = Test::Unit::AutoRunner.new(true)
t.process_args(@unit_tests)
t.run
t.run
end
end
end
@ -445,7 +445,7 @@ class PackageSpecification_1_0
key_val_pairs = additional_translations.to_a
option_pairs = key_val_pairs.select{|(k,v)| Symbol === k}
default_opts.update(Hash[*option_pairs.flatten])
(key_val_pairs - option_pairs).each do |key, val|
add_translation(kind, key, val, default_opts)
end
@ -486,7 +486,7 @@ class PackageSpecification_1_0
opts.separator " setup compiles ruby extentions and others XXX"
opts.separator " install installs files"
opts.separator " test runs unit tests"
opts.separator ""
opts.separator "Specific options:"
@ -532,7 +532,7 @@ class PackageSpecification_1_0
opts.on "--vendor", "install into distribution directories (for packagers)" do
@dirs.update VENDOR_DIRS
end
opts.separator ""
opts.separator "General options:"

128
vendor/isaac_0.9.1/test/TC_ISAAC.rb поставляемый
Просмотреть файл

@ -1,76 +1,76 @@
require 'test/unit'
if ARGV[0] == 'local'
begin
require '../crypt/ISAAC.rb'
rescue Exception
require './crypt/ISAAC.rb'
end
begin
require '../crypt/ISAAC.rb'
rescue Exception
require './crypt/ISAAC.rb'
end
else
begin
require 'crypt/ISAACC'
rescue Exception
require './crypt/ISAAC.rb'
end
begin
require 'crypt/ISAACC'
rescue Exception
require './crypt/ISAAC.rb'
end
end
class TC_ISAAC < Test::Unit::TestCase
def setup
assert_nothing_raised("Failed to create a Crypt::ISAAC object.") do
@generator = Crypt::ISAAC.new
end
end
def setup
assert_nothing_raised("Failed to create a Crypt::ISAAC object.") do
@generator = Crypt::ISAAC.new
end
end
def testKind
assert_kind_of(Crypt::ISAAC,@generator,"The created object is not a Crypt::ISAAC or subclass thereof.")
end
def testKind
assert_kind_of(Crypt::ISAAC,@generator,"The created object is not a Crypt::ISAAC or subclass thereof.")
end
def testInteger
assert_nothing_raised("Failed while generating an integer random number.") do
mynum = @generator.rand(1000000)
assert_kind_of(Integer,mynum,"The generator failed to return an integer number in response to @generator.rand(1000000).")
assert((mynum >= 0),"The generator returned a number that is less than 0 (#{mynum}).")
assert((mynum < 1000000),"The generator returned a number that is greater than or equal to 1000000 (#{mynum}).")
end
end
def testInteger
assert_nothing_raised("Failed while generating an integer random number.") do
mynum = @generator.rand(1000000)
assert_kind_of(Integer,mynum,"The generator failed to return an integer number in response to @generator.rand(1000000).")
assert((mynum >= 0),"The generator returned a number that is less than 0 (#{mynum}).")
assert((mynum < 1000000),"The generator returned a number that is greater than or equal to 1000000 (#{mynum}).")
end
end
def testFloat
assert_nothing_raised("Failed while generating a floating point random number.") do
mynum = @generator.rand()
assert_kind_of(Float,mynum,"The generator failed to return a floating point number in response to @generator.rand().")
assert((mynum >= 0),"The generator returned a number that is less than 0 (#{mynum}).")
assert((mynum < 1),"The generator returned a number that is greater than or equal to 1 (#{mynum}).")
end
end
def testFloat
assert_nothing_raised("Failed while generating a floating point random number.") do
mynum = @generator.rand()
assert_kind_of(Float,mynum,"The generator failed to return a floating point number in response to @generator.rand().")
assert((mynum >= 0),"The generator returned a number that is less than 0 (#{mynum}).")
assert((mynum < 1),"The generator returned a number that is greater than or equal to 1 (#{mynum}).")
end
end
def testIterations
puts
count = 0
assert_nothing_raised("Failed on iteration #{count} while trying to generate 100000 random numbers.") do
100000.times do
count += 1
x = @generator.rand(4294967295)
print [x].pack('V').unpack('H8') if count % 1000 == 0
if (count % 7000) == 0
print "\n"
else
print " " if count % 1000 == 0
end
end
puts "\n100000 numbers generated"
end
end
def testIterations
puts
count = 0
assert_nothing_raised("Failed on iteration #{count} while trying to generate 100000 random numbers.") do
100000.times do
count += 1
x = @generator.rand(4294967295)
print [x].pack('V').unpack('H8') if count % 1000 == 0
if (count % 7000) == 0
print "\n"
else
print " " if count % 1000 == 0
end
end
puts "\n100000 numbers generated"
end
end
def testDualStreams
g1 = nil
g2 = nil
assert_nothing_raised("Failed to pull numbers from two independent streams.") do
g1 = Crypt::ISAAC.new
g2 = Crypt::ISAAC.new
assert((g1 != g2),"The generators are the same. This should not happen.")
1000.times do
g1.rand(4294967295)
g2.rand(4294967295)
end
end
end
def testDualStreams
g1 = nil
g2 = nil
assert_nothing_raised("Failed to pull numbers from two independent streams.") do
g1 = Crypt::ISAAC.new
g2 = Crypt::ISAAC.new
assert((g1 != g2),"The generators are the same. This should not happen.")
1000.times do
g1.rand(4294967295)
g2.rand(4294967295)
end
end
end
end

Просмотреть файл

@ -1,3 +1,3 @@
h1. RubyCAS-Server
Please see "http://code.google.com/p/rubycas-server/":http://code.google.com/p/rubycas-server/ for more information.
Please see "http://code.google.com/p/rubycas-server/":http://code.google.com/p/rubycas-server/ for more information.

Просмотреть файл

@ -34,7 +34,7 @@
* MA 02111-1307 USA *
* *
****************************************************************/
var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1; var isMoz = document.implementation && document.implementation.createDocument; var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false; function curvyCorners()
{ if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object."); if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name."); if(typeof(arguments[1]) == "string")
{ var startIndex = 0; var boxCol = getElementsByClass(arguments[1]);}

Просмотреть файл

@ -1,138 +1,138 @@
body {
background-color: #E1D1F1;
font-family: "Georgia", sans-serif;
font-size: 16px;
line-height: 1.6em;
padding: 1.6em 0 0 0;
color: #333;
}
h1, h2, h3, h4, h5, h6 {
color: #444;
}
h1 {
font-family: sans-serif;
font-weight: normal;
font-size: 4em;
line-height: 0.8em;
letter-spacing: -0.1ex;
margin: 5px;
}
li {
padding: 0;
margin: 0;
list-style-type: square;
}
a {
color: #5E5AFF;
background-color: #DAC;
font-weight: normal;
text-decoration: underline;
}
blockquote {
font-size: 90%;
font-style: italic;
border-left: 1px solid #111;
padding-left: 1em;
}
.caps {
font-size: 80%;
}
#main {
width: 45em;
padding: 0;
margin: 0 auto;
}
.coda {
text-align: right;
color: #77f;
font-size: smaller;
}
table {
font-size: 90%;
line-height: 1.4em;
color: #ff8;
background-color: #111;
padding: 2px 10px 2px 10px;
border-style: dashed;
}
th {
color: #fff;
}
td {
padding: 2px 10px 2px 10px;
}
.success {
color: #0CC52B;
}
.failed {
color: #E90A1B;
}
.unknown {
color: #995000;
}
pre, code {
font-family: monospace;
font-size: 90%;
line-height: 1.4em;
color: #ff8;
background-color: #111;
padding: 2px 10px 2px 10px;
}
.comment { color: #aaa; font-style: italic; }
.keyword { color: #eff; font-weight: bold; }
.punct { color: #eee; font-weight: bold; }
.symbol { color: #0bb; }
.string { color: #6b4; }
.ident { color: #ff8; }
.constant { color: #66f; }
.regex { color: #ec6; }
.number { color: #F99; }
.expr { color: #227; }
#version {
float: right;
text-align: right;
font-family: sans-serif;
font-weight: normal;
background-color: #B3ABFF;
color: #141331;
padding: 15px 20px 10px 20px;
margin: 0 auto;
margin-top: 15px;
border: 3px solid #141331;
}
#version .numbers {
display: block;
font-size: 4em;
line-height: 0.8em;
letter-spacing: -0.1ex;
margin-bottom: 15px;
}
#version p {
text-decoration: none;
color: #141331;
background-color: #B3ABFF;
margin: 0;
padding: 0;
}
#version a {
text-decoration: none;
color: #141331;
background-color: #B3ABFF;
}
.clickable {
cursor: pointer;
cursor: hand;
}
body {
background-color: #E1D1F1;
font-family: "Georgia", sans-serif;
font-size: 16px;
line-height: 1.6em;
padding: 1.6em 0 0 0;
color: #333;
}
h1, h2, h3, h4, h5, h6 {
color: #444;
}
h1 {
font-family: sans-serif;
font-weight: normal;
font-size: 4em;
line-height: 0.8em;
letter-spacing: -0.1ex;
margin: 5px;
}
li {
padding: 0;
margin: 0;
list-style-type: square;
}
a {
color: #5E5AFF;
background-color: #DAC;
font-weight: normal;
text-decoration: underline;
}
blockquote {
font-size: 90%;
font-style: italic;
border-left: 1px solid #111;
padding-left: 1em;
}
.caps {
font-size: 80%;
}
#main {
width: 45em;
padding: 0;
margin: 0 auto;
}
.coda {
text-align: right;
color: #77f;
font-size: smaller;
}
table {
font-size: 90%;
line-height: 1.4em;
color: #ff8;
background-color: #111;
padding: 2px 10px 2px 10px;
border-style: dashed;
}
th {
color: #fff;
}
td {
padding: 2px 10px 2px 10px;
}
.success {
color: #0CC52B;
}
.failed {
color: #E90A1B;
}
.unknown {
color: #995000;
}
pre, code {
font-family: monospace;
font-size: 90%;
line-height: 1.4em;
color: #ff8;
background-color: #111;
padding: 2px 10px 2px 10px;
}
.comment { color: #aaa; font-style: italic; }
.keyword { color: #eff; font-weight: bold; }
.punct { color: #eee; font-weight: bold; }
.symbol { color: #0bb; }
.string { color: #6b4; }
.ident { color: #ff8; }
.constant { color: #66f; }
.regex { color: #ec6; }
.number { color: #F99; }
.expr { color: #227; }
#version {
float: right;
text-align: right;
font-family: sans-serif;
font-weight: normal;
background-color: #B3ABFF;
color: #141331;
padding: 15px 20px 10px 20px;
margin: 0 auto;
margin-top: 15px;
border: 3px solid #141331;
}
#version .numbers {
display: block;
font-size: 4em;
line-height: 0.8em;
letter-spacing: -0.1ex;
margin-bottom: 15px;
}
#version p {
text-decoration: none;
color: #141331;
background-color: #B3ABFF;
margin: 0;
padding: 0;
}
#version a {
text-decoration: none;
color: #141331;
background-color: #B3ABFF;
}
.clickable {
cursor: pointer;
cursor: hand;
}