Index: openacs-4/packages/auth-cas/auth-cas.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/auth-cas/auth-cas.info,v
diff -u
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/auth-cas/auth-cas.info	11 Sep 2007 17:30:40 -0000	1.1
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!-- Generated by the OpenACS Package Manager -->
+
+<package key="auth-cas" url="http://openacs.org/repository/apm/packages/auth-cas" type="apm_service">
+    <package-name>CAS Authentication Driver</package-name>
+    <pretty-plural>CAS Authentication Drivers</pretty-plural>
+    <initial-install-p>f</initial-install-p>
+    <singleton-p>t</singleton-p>
+    <auto-mount>cas</auto-mount>
+
+    <version name="1.0" url="http://openacs.org/repository/download/apm/auth-cas-1.0.apm">
+        <owner url="mailto:nima.mazloumi@gmx.de">Nima Mazloumi</owner>
+        <summary>CAS authentication drivers for acs-authentication.</summary>
+        <release-date>2007-07-02</release-date>
+        <vendor url="http://www.mazloumi.de">Mazloumi</vendor>
+        <description format="text/html">Implements the CAS authentication, password management, and other drivers for use with the acs-authentication service contracts.</description>
+        <license>GPL</license>
+        <maturity>3</maturity>
+
+        <provides url="auth-cas" version="1.0"/>
+        <requires url="acs-authentication" version="5.0d3"/>
+        <requires url="acs-subsite" version="5.4.0d5"/>
+
+        <callbacks>
+            <callback type="before-uninstall"  proc="auth::cas::before_uninstall"/>
+            <callback type="after-install"  proc="auth::cas::after_install"/>
+        </callbacks>
+        <parameters>
+            <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="CasServer"  description="The Central Authentication Server to be used. For instance: http://localhost:8080/cas/. \
+Supported are the protocols http and https if nsopenssl and tls are installed."/>
+            <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="LocalSsoHandler"  default="/cas/" description="The path to the local SSO handler. Defaults to the auth-cas instan\
+ce mounted under /cas/. Make sure you don't forget the leading and trailing slashes."/>
+            <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="ValidationType"  default="1.0" description="The type of validation. Defaults to 1.0. Possible values are 1.0 and \
+2.0. The first returns a list of values. The second an XML."/>
+        </parameters>
+
+    </version>
+</package>
Index: openacs-4/packages/auth-cas/lib/login.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/auth-cas/lib/login.tcl,v
diff -u
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/auth-cas/lib/login.tcl	11 Sep 2007 17:30:40 -0000	1.1
@@ -0,0 +1,14 @@
+#this is an include and requires a return_url parameter
+
+set authenticated_p [ad_get_client_property auth-cas authenticated_p]
+
+#if user was not authenticated redirect to cas-web module as defined in the parameters
+if {[empty_string_p $authenticated_p] || $authenticated_p != 1} {
+	#lets load the required parameters
+	auth::cas::authentication::GetParameters
+	ns_log Debug "auth-cas: Redirecting to $cas(server)login?service=[ns_conn location]$cas(handler)"
+	ad_returnredirect "$cas(server)login?service=[ns_conn location]$cas(handler)"
+    }
+} else {
+    ad_returnredirect $return_url
+}
Index: openacs-4/packages/auth-cas/tcl/auth-cas-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/auth-cas/tcl/auth-cas-procs.tcl,v
diff -u
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/auth-cas/tcl/auth-cas-procs.tcl	11 Sep 2007 17:30:40 -0000	1.1
@@ -0,0 +1,197 @@
+ad_library {
+    Procs for cas authentication
+
+    @author Nima Mazloumi nima.mazloumi@gmx.de)
+    @creation-date 2007-06-29
+}
+
+namespace eval auth {}
+namespace eval auth::cas {}
+namespace eval auth::cas::authentication {}
+
+ad_proc -private auth::cas::after_install {} {} {
+    set spec {
+        contract_name "auth_authentication"
+        owner "auth-cas"
+        name "CAS"
+        pretty_name "CAS"
+        aliases {
+            Authenticate auth::cas::authentication::Authenticate
+            GetParameters auth::cas::authentication::GetParameters
+            MergeUser auth::cas::authentication::MergeUser
+        }
+    }
+
+    set auth_impl_id [acs_sc::impl::new_from_spec -spec $spec]
+}
+
+ad_proc -private auth::cas::before_uninstall {} {} {
+    acs_sc::impl::delete -contract_name "auth_authentication" -impl_name "CAS"
+}
+
+#####
+#
+# CAS Authentication Driver
+#
+#####
+
+ad_proc -private auth::cas::authentication::Authenticate {
+    username
+    password
+    {parameters {}}
+    {authority_id {}}
+} {
+    Implements the Authenticate operation of the auth_authentication service contract for CAS. 
+    This proc is only called if the oacs login page was used.
+    We simply redirect to CAS here
+} {
+    ad_returnredirect "[lindex $parameters 0]/login?service=[ns_conn location][lindex $parameters 5]"
+}
+
+ad_proc -private auth::cas::authentication::GetParameters {} {
+    Implements the GetParameters operation of the auth_authentication 
+    service contract for CAS. Returns a list as well as upvars an array called cas
+} {
+    # we upvar the parameters as well for named access to the parameters
+    upvar cas _cas
+
+    set server [parameter::get_from_package_key -parameter CasServer -package_key "auth-cas"]
+    regexp -nocase {^(http.?://)?([^:/]+)(:([0-9]+))?(/.*)} $server tX_x tX_protocol tX_server tX_y tX_port tX_path
+
+    set _cas(host) $tX_server
+    set _cas(path) $tX_path
+    set _cas(port) $tX_port
+    set _cas(protocol) $tX_protocol
+    set _cas(handler) [parameter::get_from_package_key -parameter LocalSsoHandler -package_key "auth-cas"]
+
+    #in some cases not this OpenACS instance but a third service shall be used for ticket validation use that if provided or default to the oacs instance
+    set _cas(type) [parameter::get_from_package_key -parameter ValidationType -package_key "auth-cas"]
+    set _cas(server) $server
+
+    #proc must return a list as well in for the service contract auth::cas::authentication::Authenticate to work correctly
+    return [list $_cas(server) $_cas(host) $_cas(path) $_cas(port) $_cas(protocol) $_cas(handler) $_cas(type)]
+}
+
+ad_proc -private auth::cas::authentication::MergeUser {
+    from_user_id
+    to_user_id
+    {authority_id ""}
+} {
+    Required but not used MergeUser operation for auth_authentication service contract
+} {
+    #do nothing
+}
+
+ad_proc -private auth::cas::authentication::validate {
+    -ticket
+    {-service ""}
+    {-return_url ""}
+} {
+    Validates a ticket or tries to get a new ticket from CAS server. Supported are http/https as well as CAS 1.0 and 2.0 validation.
+} {
+    auth::cas::authentication::GetParameters
+
+    if {[empty_string_p $return_url]} {
+	set return_url [parameter::get_from_package_key -package_key acs-kernel -parameter IndexRedirectUrl]
+    }
+
+    #if no external service is given we use the default
+    if {[empty_string_p $service]} {
+	set service "[ns_conn location]$cas(handler)"
+    }
+    
+    #if no ticket passed get a ticket
+    if {[empty_string_p $ticket]} {
+
+	ns_log Debug "auth-cas: No ticket, redirecting to $cas(server)login?service=$service"
+	ad_returnredirect "$cas(server)login?service=$service"
+
+    } else {
+
+	#CAS validation version
+	switch $cas(type) {
+	    1.0 {
+		set validatePath validate
+	    }
+	    2.0 {
+		set validatePath serviceValidate
+	    }
+	}
+
+	set url "$cas(server)$validatePath?ticket=$ticket&service=$service"
+
+	#get cas response for the given ticket
+	switch $cas(protocol) {
+	    http:// {
+		set response [ns_httpget $url]
+	    }
+	    https:// {
+                #alternatively we can use nsopenssl module if available
+                #set response [ns_httpsget $url]
+                package require http
+                package require tls
+                http::register https 443 [list ::tls::socket]
+                set handle [http::geturl $url]
+                set response [::http::data $handle]
+	    }
+	}
+
+	ns_log Debug "auth-cas: $url\n$response"
+
+	set message ""
+	set validation_failed_p 1
+	
+	#parse response depending on the cas validation version
+        switch $cas(type) {
+	    1.0 {
+		#validation failed
+		if {[lindex $response 0] == "no"} {
+		    set validation_failed_p 1
+		    set message "<b><small><center><font color=\"red\">Validation failed for ticket $ticket</font></center></small></b>"
+		}
+		
+		#validation succeeded, check if user exists and create cookie
+		if {[lindex $response 0] == "yes"} {
+		    set username [lindex $response 1]
+		    set validation_failed_p 0
+		}
+	    }
+	    2.0 {
+		set query "//cas:serviceResponse/cas:authenticationSuccess/cas:user/text()"
+		dom parse $response document
+		$document documentElement root
+		set textNode [$root selectNodes $query]
+		if {![empty_string_p $textNode]} {
+		    #validation succeeded, check if user exists and create cookie
+		    set username [$textNode nodeValue]
+		    set validation_failed_p 0
+		} else {
+		    #validation failed, return error message
+		    set validation_failed_p 1
+		    set query "//cas:serviceResponse/cas:authenticationFailure"
+		    dom parse $response document
+		    $document documentElement root
+		    set failureNode [$root selectNodes $query]
+		    set errorCode [$failureNode getAttribute code]
+		    set textNode [$failureNode selectNodes text()]
+		    set reason [$textNode nodeValue]
+		    set message "<b><small><center><font color=\"red\">$reason ($errorCode)</font></center></small></b>"
+		}
+	    }
+	}
+
+	if {$validation_failed_p} {
+	    ad_set_client_property auth-cas authenticated_p 0
+	    util_user_message -html -message $message
+	} else {
+	    set authority_id [db_string select_first_authority {select authority_id from auth_authorities order by sort_order limit 1} -default [auth::authority::local]]
+	    set user_id [acs_user::get_by_username -authority_id $authority_id -username $username]
+	    
+	    # Issue login cookie if login was successful
+	    auth::issue_login -user_id $user_id -account_status "ok"
+	    ad_set_client_property auth-cas authenticated_p 1
+	}
+
+	ad_returnredirect $return_url
+    }
+}
Index: openacs-4/packages/auth-cas/www/index.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/auth-cas/www/index.tcl,v
diff -u
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/auth-cas/www/index.tcl	11 Sep 2007 17:30:40 -0000	1.1
@@ -0,0 +1,24 @@
+# Service Page for CAS
+
+ad_page_contract {    
+    
+    @author Nima Mazloumi (nima.mazloumi@gmx.de)
+    @creation-date 2007-07-03
+} {
+    {ticket ""}
+} -properties {
+} -validate {
+} -errors {
+}
+
+set authenticated_p [ad_get_client_property auth-cas authenticated_p]
+set return_url [parameter::get_from_package_key -package_key acs-kernel -parameter IndexRedirectUrl]
+
+#if invalid session
+if {[empty_string_p $authenticated_p] || $authenticated_p != 1} {
+    ns_log Debug "auth-cas: authenticated_p '$authenticated_p' validating ticket"
+    auth::cas::authentication::validate -ticket $ticket -return_url $return_url
+} else {
+    ns_log Debug "auth-cas: authenticated_p '$authenticated_p' redirecting to $return_url"
+    ad_returnredirect $return_url
+}
Index: openacs-4/packages/auth-cas/www/doc/index.html
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/auth-cas/www/doc/index.html,v
diff -u
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/auth-cas/www/doc/index.html	11 Sep 2007 17:30:40 -0000	1.1
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Auth-CAS</title>
+</head>
+<body>
+<h1>Auth-CAS</h1>
+<p>Nima Mazloumi (nima.mazloumi@gmx.de)</p>
+<h2>Introduction</h2>
+<p>The Central Authentication Service [1] is a mechanism that allows Single-Sign-On
+      (SSO) for web-based applications. When activated authentication takes
+      place on a central authentication service and integrated applications
+      provide a CAS client that forwards login and logout requests to a central
+      service and receive a ticket instead. This ticket is used against the
+      central service to validate an active session. If the validation succeeds
+      that user is logged-in automatically. If not the user has to provide a
+      username and a password.
+<p>
+      While the clear benefit is a SSO a SSOut is not supported for CAS releases
+	prio to 3.1. The current package only supports SSO. SSOut is left for
+	future releases. Therefore a logout in OpenACS is not reflected in
+	other integrated systems since the CAS cookie is valid for the whole
+	browser session. To logout safely the user <font color="red"><b>MUST</b></font> close the browser!
+<h2>Dependencies</h2>
+To support https validation this package requires TLS 1.5 or up. If you use OpenSSL/nsopenssl uncomment the <code>ns_httpsget</code> statement in <code>auth-cas-procs.tcl</code> and comment out the tls part.
+<h2>Installation</h2>
+<ol>
+<li>Install tls 1.5
+<pre>
+# Install TLS for https assuming you have installed AOLServer under /usr/local/aolserver45
+wget http://dfn.dl.sourceforge.net/sourceforge/tls/tls1.5.0-src.tar.gz
+tar xzpf tls1.5.0-src.tar.gz
+cd tls1.5
+./configure --with-ssl-dir=/usr --with-tcl=/usr/local/aolserver45/lib --enable-threads --enable-shared --prefix=/usr/local/aolserver45 --exec-prefix=/usr/local/aolserver45
+make install
+</pre>
+or install nsopenssl module. Make sure you change <code>auth-cas-procs.tcl</code> to use <code>ns_httpsget</code>.
+<pre>
+# Install OpenSSL module for https
+# Assuming that OpenSSL is installed an available under /usr/local/ssl and AOLServer under /usr/local/aolserver45
+cd /usr/local/src/aolserver45
+cvs -z3 -d:pserver:anonymous@aolserver.cvs.sourceforge.net:/cvsroot/aolserver co nsopenssl
+cd nsopenssl
+make install OPENSSL=/usr/local/ssl AOLSERVER=/usr/local/aolserver45
+</pre>
+<li>Install this package. An instance of it will be mounted under <code>/cas/</code>. Important is the <code>CasServer</code> parameter. You don't need to change the other parameters. If you don't want to use the standard auth-cas instance change the <code>LocalSsoHandler</code> (defaults to <code>/cas/</code>). Also you can choose between CAS 1.0 and 2.0 validation (parameter <code>ValidationType</code>).
+<li>Open <a href="/acs-admin/auth/">Authorities Administration</a> and create a new authority 'CAS'. Set the authentication parameter to "CAS". Password Management and Account Registration can be set to 'local'.
+<li>Create a new user that exists on your CAS Server, grant the user site-wide admin rights and change the users authority from 'local' to 'CAS'. Write down the <code>user_id</code> of that user. You will need it in case something goes wrong.
+<li>Change the main site subsite parameter <code>LoginTemplate</code> to <code>/packages/auth-cas/lib/login</code>
+<li>Go to the authorities. Move the 'CAS' authority up, enable it and disable the 'local' authority.
+<li>Logout. The system should redirect to the CAS server and request account information. Once you have passed in the correct data you should be forwarded to your OpenACS installation.
+<li>In case something goes wrong create a file called: <code>youropenacsroot/www/autologin.tcl</code> and change the <code>user_id</code> accordingly:
+<pre>
+set user_id foo
+auth::issue_login -user_id $user_id -account_status "ok"
+parameter::set_value -package_id [subsite::main_site_id] -parameter LoginTemplate -value /packages/acs-subsite/lib/login
+ad_set_client_property auth-cas authenticated_p 1
+ad_returnredirect [parameter::get_from_package_key -package_key acs-kernel -parameter IndexRedirectUrl]
+</pre>
+This code will grant you access to the OpenACS installation and reset the subsite parameter.
+</ol>
+<h2>Features</h2>
+<ul>
+<li>CAS 1.0 and 2.0 validation
+<li>HTTP and HTTPS validation if TLS or NSOpenSSL is installed
+<li>SSO
+</ul>
+<h2>Restrictions</h2>
+<ul>
+<li>No SSOut
+<li>CAS client instances must be top level site nodes
+<li>acs-subsite 5.4.0 or up required for <code>LoginTemplate</code> parameter
+</ul>
+<h2>References</h2>
+[1] http://www.ja-sig.org/products/cas/
+</body>
+</html>
Index: openacs-4/packages/auth-cas/www/doc/ws-support.html
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/auth-cas/www/doc/ws-support.html,v
diff -u
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/auth-cas/www/doc/ws-support.html	11 Sep 2007 17:30:40 -0000	1.1
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Web Service Support</title>
+</head>
+<body>
+<h1>Web Service Support</h1>
+<p>Nima Mazloumi (nima.mazloumi@gmx.de)</p>
+<p>See under <code>cas-auth/lib/login.tcl</code> for a web service based support. In order
+to get it working you need tsoap. Comment out in <code>tsoap/tcl/SOAP-procs.tcl</code> the lines
+<pre>package require SOAP::Utils;
+package require rpcvar;</pre>
+<p>Rename <code>rpcvar-procs.tcl</code> to <code>00-rpcvar-procs.tcl</code> Otherwise <code>SOAP-procs.tcl</code> won't load correctly.
+<p>You also need to install <code>tls</code> to get <code>tsoap</code> load correctly.