diff -ru mantisbt-1.2.1/config_defaults_inc.php mantisbt-1.2.1.CAS/config_defaults_inc.php
--- mantisbt-1.2.1/config_defaults_inc.php	2010-04-24 02:28:34.000000000 +0800
+++ mantisbt-1.2.1.CAS/config_defaults_inc.php	2010-04-24 16:03:46.000000000 +0800
@@ -1629,6 +1629,83 @@
 	 */
 	$g_hr_width				= 50;
 
+
+	/***********************
+	 * Mantis CAS Settings *
+	 ***********************/
+
+	# --- using phpCAS -------------
+	/**
+	 * @global string $g_cas_server
+	 */
+	$g_cas_server = 'example.com.au';
+
+	/**
+	 * @global int $g_cas_port
+	 */
+	$g_cas_port = 443;
+
+	/**
+	 * The CAS path on the server. E.g. '/cas'
+	 * @global int $g_cas_uri
+	 */
+	$g_cas_uri = '';
+
+	/**
+	 * @global $g_cas_version string
+	 */
+	$g_cas_version = '2.0';
+
+	# --- CAS + LDAP -------------
+	/**
+	 * Translate CAS username through LDAP.
+	 * @global $g_cas_use_ldap int
+	 */
+	$g_cas_use_ldap     = OFF;
+
+	/**
+	 * The LDAP field matching the Mantis username.
+	 * @global $g_ldap_mantis_udi string
+	 */
+	$g_ldap_mantis_uid  = 'uid';
+
+	/**
+	 * Should Mantis update user details from LDAP while authenticating with CAS?
+	 * @global $g_cas_ldap_update int
+	 */
+	$g_cas_ldap_update  = OFF;
+
+	/**
+	 * E.g. 'cn,userpassword'.
+	 * @global $g_cas_ldap_update_fields string
+	 */
+	$g_cas_ldap_update_fields = '';
+
+	/**
+	 * E.g. 'realname,password'.
+	 * @global $g_cas_ldap_update_map string
+	 */
+	$g_cas_ldap_update_map    = '';
+
+	/**
+	 * This is the field in LDAP to use to set the user's language preference.
+	 * @global $g_ldap_language_field string
+	 */
+	$g_ldap_language_field = '';
+
+	/**
+	 * E.g. 'en,zh_hans,ko'.
+	 * @global $g_ldap_language_keys string
+	 */
+	$g_ldap_language_keys = '';
+
+	/**
+	 * E.g. 'english,chinese_simplified,korean'.
+	 * @global $g_ldap_language_values string
+	 */
+	$g_cas_ldap_update_values    = '';
+
+
 	/**************************
 	 * MantisBT LDAP Settings *
 	 **************************/
@@ -2478,7 +2555,7 @@
 
 	/**
 	 * login method
-	 * CRYPT or PLAIN or MD5 or LDAP or BASIC_AUTH
+	 * CRYPT or PLAIN or MD5 or LDAP or BASIC_AUTH or CAS_AUTH
 	 * You can simply change this at will. MantisBT will try to figure out how the passwords were encrypted.
 	 * @global int $g_login_method
 	 */
Only in mantisbt-1.2.1.CAS: config_inc.php
diff -ru mantisbt-1.2.1/core/authentication_api.php mantisbt-1.2.1.CAS/core/authentication_api.php
--- mantisbt-1.2.1/core/authentication_api.php	2010-04-24 02:28:34.000000000 +0800
+++ mantisbt-1.2.1.CAS/core/authentication_api.php	2010-04-24 16:43:34.000000000 +0800
@@ -53,6 +53,177 @@
 $g_cache_current_user_id = null;
 
 /**
+ * Initialize phpCAS.
+ */
+function auth_cas_init() {
+        # phpCAS must be installed in the include path
+        # or in the Mantis directory.
+        require_once('CAS/CAS.php');
+
+        static $s_initialized=false;
+
+        if (! $s_initialized ) {
+                phpCAS::setDebug();
+        ## These should be set in config_inc.php
+                $t_server_version = config_get( 'cas_version' );
+                $t_server_cas_server = config_get( 'cas_server' );
+                $t_server_port = config_get( 'cas_port' );
+                $t_server_uri = config_get( 'cas_uri' );
+                $t_start_session = (boolean)FALSE; # Mantis takes care of its own session
+
+                phpCAS::client($t_server_version, $t_server_cas_server, $t_server_port, $t_server_uri, $t_start_session);
+                if (method_exists('phpCAS', 'setNoCasServerValidation')) {
+                        // no SSL validation for the CAS server
+                        phpCAS::setNoCasServerValidation();
+                }
+
+                $s_initialized = true;
+        }
+
+}
+
+
+/**
+ * Fetches the user's CAS name, authenticating if needed.
+ * Can translate CAS login name to Mantis username through LDAP.
+ */
+function auth_cas_get_name()
+{
+        # Get CAS username from phpCAS
+        auth_cas_init();
+        phpCAS::forceAuthentication();
+        $t_cas_id = phpCAS::getUser();
+
+        # If needed, translate the CAS username through LDAP
+        $t_username = $t_cas_id;
+        if (config_get( 'cas_use_ldap', false )) {
+                $t_username = auth_cas_ldap_translate( $t_cas_id );
+        }
+        return $t_username;
+}
+
+
+/**
+ * Takes an ID string, and looks up the LDAP directory to find
+ * the matching username for Mantis.
+ *
+ * Optionally, also update the user information in the Mantis user
+ * table.
+ *
+ * @param $p_cas_id string Typically, the username given by phpCAS.
+ * @param $p_update_user bool Whether or not to update user details from LDAP.
+ */
+function auth_cas_ldap_translate( $p_cas_id, $p_update_user='' )
+{
+
+        # Please make sure the Mantis CAS and LDAP settings are set in config_inc.php
+
+        $t_ldap_organization    = config_get( 'ldap_organization' );
+        $t_ldap_root_dn                 = config_get( 'ldap_root_dn' );
+
+        # Required fields in LDAP for CAS
+        $t_ldap_language_field = config_get( 'ldap_language_field', '' );
+        $t_ldap_uid_field = config_get( 'ldap_uid_field', 'uid' ) ;
+        $t_ldap_mantis_uid = config_get( 'ldap_mantis_uid', 'uid' );
+        $t_ldap_required = array( $t_ldap_uid_field, $t_ldap_mantis_uid, 'dn' );
+        if ($t_ldap_language_field) {
+                // Add language field to attributes list only if it is configured.
+                $t_ldap_required[] = $t_ldap_language_field;
+        }
+        $t_ldap_required = array_combine( $t_ldap_required, $t_ldap_required );
+
+        # User-defined fields to fetch from LDAP...
+        $t_ldap_fields = explode( ',', config_get( 'cas_ldap_update_fields' ) );
+        $t_ldap_fields = array_combine( $t_ldap_fields, $t_ldap_fields );
+        # ...which are mapped to Mantis user fields
+        $t_ldap_map = explode( ',', config_get( 'cas_ldap_update_map' ) );
+        $t_ldap_map = array_combine( $t_ldap_map, $t_ldap_map );
+
+        # Build LDAP search filter, attribute list from CAS ID
+        $t_search_filter = "(&$t_ldap_organization($t_ldap_uid_field=$p_cas_id))";
+        $t_search_attrs = array_values($t_ldap_required + $t_ldap_fields);      # array union
+
+        # Use Mantis ldap_api to connect to LDAP
+        $t_ds = ldap_connect_bind();
+        $t_sr   = ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs );
+        $t_info = ldap_get_entries( $t_ds, $t_sr );
+        # Parse the LDAP entry to find the Mantis username
+        if ( $t_info ) {
+                # Get Mantis username
+                $t_username = $t_info[0][$t_ldap_mantis_uid][0];
+
+                # @@@ The fact that we got here means the user is authenticated
+                # @@@ by CAS, and has an LDAP entry.
+                # @@@ We might as well update other user details since we are here.
+
+                # If no argument given, check settings
+                if ( '' == $p_update_user ) {
+                        $p_update_user = config_get( 'cas_ldap_update', FALSE );
+                }
+                # If there's a user record, then update it
+                if ( $p_update_user ) {
+                        # Only proceed if the field map arrays are the same length
+                        $t_field_map = array_combine( $t_ldap_fields, $t_ldap_map );
+                        if ($t_field_map) {
+                                # If user is new, then we must create their account before updating it
+                                # @@@ ( make sure $g_allow_blank_email == ON )
+                                $t_userid = user_get_id_by_name($t_username);
+                                if ( false == $t_userid ) {
+                                        user_create( $t_username, '' );
+                                        # @@@ Wow, this is pretty lame
+                                        $t_userid = user_get_id_by_name($t_username);
+                                }
+                                # @@@ maybe we can optimize this to write all fields at once?
+                                foreach ( $t_field_map as $key=>$t_userfield ) {
+                                        if (isset($t_info[0][$key][0])) {
+                                                user_set_field( $t_userid, $t_userfield, $t_info[0][$key][0] );
+                                        }
+                                }
+                        }
+
+                        // Update user's overall language preference
+                        if ($t_ldap_language_field) {
+                                $t_language = $t_info[0][$t_ldap_language_field][0];
+                                // Map the LDAP language field to Mantis' language field if needed
+                                $t_language_keys = config_get( 'ldap_language_keys', '');
+                                $t_language_values = config_get( 'ldap_language_values', '');
+                                $t_language_map = array_combine(
+                                        explode(',', $t_language_keys),
+                                        explode(',', $t_language_values)
+                                );
+                                if (isset($t_language_map[$t_language])) {
+                                        $t_language = $t_language_map[$t_language];
+                                }
+                                user_pref_set_pref($t_userid, 'language', $t_language);
+                        }
+                }
+        }
+        ldap_free_result( $t_sr );
+        ldap_unbind( $t_ds );
+
+        return $t_username;
+}
+
+
+/**
+ * Logs out of CAS, redirecting to Mantis on re-login.
+ * User should already be logged out of Mantis by the time this is called.
+ * @see auth_logout()
+ */
+function auth_cas_logout()
+{
+        $t_path = config_get('path');
+
+        auth_cas_init();
+        if (method_Exists('phpCAS', 'logoutWithUrl')) {
+                phpCAS::logoutWithUrl($t_path);
+        } else {
+                phpCAS::logout($t_path);
+        }
+}
+
+
+/**
  * Check that there is a user logged-in and authenticated
  * If the user's account is disabled they will be logged out
  * If there is no user logged in, redirect to the login page
@@ -182,7 +353,9 @@
 	$t_login_method = config_get( 'login_method' );
 
 	if ( false === $t_user_id ) {
-		if ( BASIC_AUTH == $t_login_method ) {
+		if ( in_array( $t_login_method, array( BASIC_AUTH, CAS_AUTH ) ) ) {
+			# attempt to create the user if using BASIC_AUTH or CAS_AUTH
+			# ( note: CAS_AUTH must have $g_allow_blank_email == ON )
 			$t_auto_create = true;
 		} else if ( LDAP == $t_login_method && ldap_authenticate_by_username( $p_username, $p_password ) ) {
 			$t_auto_create = true;
@@ -311,6 +484,10 @@
 	if( HTTP_AUTH == config_get( 'login_method' ) ) {
 		auth_http_set_logout_pending( true );
 	}
+	elseif ( CAS_AUTH == config_get( 'login_method' ) ) {
+		# Redirect to CAS page to logout
+		auth_cas_logout();
+	}
 
 	session_clean();
 }
@@ -324,6 +501,8 @@
 	switch( config_get( 'login_method' ) ) {
 		case HTTP_AUTH:
 			return true;
+		case CAS_AUTH:
+			return true;
 	}
 	return false;
 }
@@ -342,6 +521,10 @@
 	if( LDAP == $t_configured_login_method ) {
 		return ldap_authenticate( $p_user_id, $p_test_password );
 	}
+	elseif ( CAS_AUTH == $t_configured_login_method ) {
+		# CAS already took care of password verification for us
+		return true;
+	}
 
 	$t_password = user_get_field( $p_user_id, 'password' );
 	$t_login_methods = Array(
@@ -617,7 +800,7 @@
  * @access public
  */
 function auth_reauthenticate() {
-	if( config_get_global( 'reauthentication' ) == OFF || BASIC_AUTH == config_get( 'login_method' ) || HTTP_AUTH == config_get( 'login_method' ) ) {
+	if( config_get_global( 'reauthentication' ) == OFF || in_array(config_get('login_method'), array(BASIC_AUTH, HTTP_AUTH, CAS_AUTH)) ) {
 		return true;
 	}
 
diff -ru mantisbt-1.2.1/core/constant_inc.php mantisbt-1.2.1.CAS/core/constant_inc.php
--- mantisbt-1.2.1/core/constant_inc.php	2010-04-24 02:28:34.000000000 +0800
+++ mantisbt-1.2.1.CAS/core/constant_inc.php	2010-04-24 16:23:23.000000000 +0800
@@ -134,6 +134,7 @@
 define( 'LDAP', 4 );
 define( 'BASIC_AUTH', 5 );
 define( 'HTTP_AUTH', 6 );
+define( 'CAS_AUTH', 7);
 
 # file upload methods
 define( 'DISK', 1 );
diff -ru mantisbt-1.2.1/login.php mantisbt-1.2.1.CAS/login.php
--- mantisbt-1.2.1/login.php	2010-04-24 02:28:34.000000000 +0800
+++ mantisbt-1.2.1.CAS/login.php	2010-04-24 16:26:17.000000000 +0800
@@ -33,6 +33,13 @@
 	$f_from			= gpc_get_string( 'from', '' );
 	$f_secure_session = gpc_get_bool( 'secure_session', false );
 
+	if ( CAS_AUTH == config_get( 'login_method' ) ) {
+		# This will detour to the CAS login page if needed
+		$f_password = '';
+		$f_username = auth_cas_get_name();
+		# User is always authenticated by this point
+	}
+
 	$f_username = auth_prepare_username($f_username);
 	$f_password = auth_prepare_password($f_password);
 
