--- mantisbt-2.24.3/config_defaults_inc.php
+++ ../mantisbt/config_defaults_inc.php
@@ -2006,6 +2006,108 @@
  */
 $g_wrap_in_preformatted_text = ON;

+/***********************
+ * 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 string $g_cas_uri
+ */
+$g_cas_uri = '';
+
+/**
+ * The CAS validation URL to the server
+ * @global string $g_cas_validation
+ */
+$g_cas_validate = '';
+
+/**
+ * Protocol version 2.0 (to use CAS) or S1 (to use SAML)
+ * @global string $g_cas_version
+ */
+$g_cas_version = '2.0';
+
+/**
+ * Full path incl filename to the cas debug log file
+ * @global string $g_cas_debug
+ */
+$g_cas_debug = '';
+
+/**
+ * When using SAML the CAS can provide user attributes
+ * @global boolean $g_cas_saml_attributes
+ */
+$g_cas_saml_attributes = OFF;
+
+/**
+ * Array with two entries: name => ..., mail => ...
+ * Look in your WEB-INF/deployerConfigContext.xml at the CAS server
+ * @global array $g_cas_saml_map
+ */
+$g_cas_saml_map = array( 'name' => '', 'mail' => '' );
+
+
+# --- 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 Authentication and LDAP Settings #
 #############################################
--- mantisbt-2.24.3/core/authentication_api.php
+++ ../mantisbt/core/authentication_api.php
@@ -75,6 +75,182 @@
 $g_cache_current_user_id = NO_USER;

 /**
+ * Initialize phpCAS.
+ */
+function auth_cas_init() {
+    # phpCAS must be installed in the include path
+    # or in the Mantis directory.
+    require_once('CAS.php');
+
+    static $s_initialized=false;
+
+    if (! $s_initialized ) {
+        phpCAS::setDebug( config_get_global( 'cas_debug' ) );
+
+        ## These should be set in config_inc.php
+        $t_server_version = config_get_global( 'cas_version' );
+        $t_server_cas_server = config_get_global( 'cas_server' );
+        $t_server_port = config_get_global( 'cas_port' );
+        $t_server_uri = config_get_global( '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);
+        phpCAS::setCasServerCACert('/usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt');
+
+        $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 );
+    }
+    elseif (config_get( 'cas_saml_attributes', false )) {
+        $t_cas_attribmap = config_get( 'cas_saml_map', array() );
+        $t_cas_attrib_name = $t_cas_attribs[$t_cas_attribmap['name']];
+        $t_cas_attrib_mail = $t_cas_attribs[$t_cas_attribmap['mail']];
+        if ( user_get_id_by_name($t_cas_id) == false ) {
+            user_create( $t_cas_id, '', $t_cas_attrib_mail, null, false, true, $t_cas_attrib_name );
+         }
+    }
+
+    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_global( 'ldap_organization' );
+    $t_ldap_root_dn         = config_get_global( 'ldap_root_dn' );
+
+    # Required fields in LDAP for CAS
+    $t_ldap_language_field = config_get_global( 'ldap_language_field', '' );
+    $t_ldap_uid_field = config_get_global( 'ldap_uid_field', 'uid' ) ;
+    $t_ldap_mantis_uid = config_get_global( '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_global( '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_global( '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_global( '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_global( 'ldap_language_keys', '');
+                $t_language_values = config_get_global( '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_global('path');
+
+    auth_cas_init();
+    if (method_Exists('phpCAS', 'logoutWithRedirectService')) {
+        phpCAS::logoutWithRedirectService($t_path);
+    } else {
+        phpCAS::logout($t_path);
+    }
+}
+
+
+/**
  * Gets set of flags for authentication for the specified user.
  * @param int|null|bool $p_user_id The user id or null for logged in user or NO_USER/false for user that doesn't exist
  *                 in the system, that may be auto-provisioned.
@@ -671,6 +847,10 @@
        if( HTTP_AUTH == config_get_global( 'login_method' ) ) {
         auth_http_set_logout_pending( true );
        }
+        elseif ( CAS_AUTH == config_get_global( 'login_method' ) ) {
+                # Redirect to CAS page to logout
+                auth_cas_logout();
+        }

        session_clean();
 }
@@ -681,7 +861,7 @@
  * @access public
  */
 function auth_automatic_logon_bypass_form() {
-       return config_get_global( 'login_method' ) == HTTP_AUTH;
+       return (config_get_global( 'login_method' ) == HTTP_AUTH || config_get_global( 'login_method' ) == CAS_AUTH);
 }

 /**
@@ -718,6 +898,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;
+        }

        if( !auth_can_use_standard_login( $p_user_id ) ) {
         return false;
@@ -992,7 +1176,7 @@
  * @access public
  */
 function auth_reauthenticate() {
-       if( !auth_reauthentication_enabled() || BASIC_AUTH == config_get_global( 'login_method' ) || HTTP_AUTH == config_get_global( 'login_method' ) ) {
+       if( !auth_reauthentication_enabled() || BASIC_AUTH == config_get_global( 'login_method' ) || HTTP_AUTH == config_get_global( 'login_method' ) || CAS_AUTH == config_get_global( 'login_method' ) ) {
         return true;
        }

--- mantisbt-2.24.3/core/constant_inc.php
+++ ../mantisbt/core/constant_inc.php
@@ -149,6 +149,7 @@
 define( 'LDAP', 4 );
 define( 'BASIC_AUTH', 5 );
 define( 'HTTP_AUTH', 6 );
+define( 'CAS_AUTH', 7 );

 # file upload methods
 define( 'DISK', 1 );
--- mantisbt-2.24.3/login.php
+++ ../mantisbt/login.php
@@ -54,6 +54,13 @@
        $t_return = 'admin/install.php';
 }

+if ( CAS_AUTH == config_get_global( '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 );
