From b767230c7a3135e3e1f0360738d9ecbde60c28df Mon Sep 17 00:00:00 2001
From: Alberto Zigoni <alberto.zigoni@gmail.com>
Date: Tue, 8 Feb 2011 01:50:54 +0200
Subject: [PATCH] Enable MantisBT to participate in SSO scenarios

When MantisBT is part of a larger installation it is not unusual
for logins to be delegated to another service, which in turn sets
an HTTP header with the authentication result. This commit allows
MantisBT to participate in such scenarios.

Signed-off-by: Robert Munteanu <robert.munteanu@gmail.com>
---
 api/soap/mc_api.php         |    6 ++++++
 config_defaults_inc.php     |   16 ++++++++++++++--
 core/authentication_api.php |   11 ++++++++++-
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/api/soap/mc_api.php b/api/soap/mc_api.php
index 2306eb1..cef1ffa 100644
--- a/api/soap/mc_api.php
+++ b/api/soap/mc_api.php
@@ -36,6 +36,12 @@ function mci_is_mantis_offline() {
 
 # return user_id if successful, otherwise false.
 function mci_check_login( $p_username, $p_password ) {
+
+	$t_login_method = config_get( 'login_method' );
+	if(HTTP_AUTH == $t_login_method) {
+		$p_username = auth_prepare_username('');
+	}
+
 	if( mci_is_mantis_offline() ) {
 		return false;
 	}
diff --git a/config_defaults_inc.php b/config_defaults_inc.php
index aab2e35..8061226 100644
--- a/config_defaults_inc.php
+++ b/config_defaults_inc.php
@@ -2639,13 +2639,25 @@ $g_allow_no_category = OFF;
 
 /**
  * login method
- * CRYPT or PLAIN or MD5 or LDAP or BASIC_AUTH. You can simply change this at
- * will. MantisBT will try to figure out how the passwords were encrypted.
+ * CRYPT or PLAIN or MD5 or LDAP or BASIC_AUTH or HTTP_AUTH. You can simply change
+ * this at will. MantisBT will try to figure out how the passwords were encrypted.
  * @global int $g_login_method
  */
 $g_login_method = MD5;
 
 /**
+ * SSO regular expression for matching users
+ * 
+ * <p>This is only useful when <tt>$g_login_method</tt> is set to <tt>HTTP_AUTH</tt>
+ * as it will extract the username from the HTTP headers.</p>
+ * 
+ * <p>Example value: <tt>'/^(.*)@example.com$/i';</tt></p>
+ * 
+ * @global int $g_sso_user_regex
+ */
+$g_sso_user_regex = '';
+
+/**
  * limit reporters. Set to ON if you wish to limit reporters to only viewing
  * bugs that they report.
  * @global int $g_limit_reporters
diff --git a/core/authentication_api.php b/core/authentication_api.php
index 631fb0c..0dc8c28 100644
--- a/core/authentication_api.php
+++ b/core/authentication_api.php
@@ -146,6 +146,12 @@ function auth_prepare_username( $p_username ) {
 			break;
 		case HTTP_AUTH:
 			if( !auth_http_is_logout_pending() ) {
+				
+			    if (isset($_SERVER['REMOTE_USER'])) {
+					preg_match(config_get('sso_user_regex'), $_SERVER['REMOTE_USER'], $user_match);
+					$f_username = $user_match[1];
+				}
+
 				if( isset( $_SERVER['PHP_AUTH_USER'] ) ) {
 					$f_username = $_SERVER['PHP_AUTH_USER'];
 				}
@@ -178,6 +184,9 @@ function auth_prepare_password( $p_password ) {
 			break;
 		case HTTP_AUTH:
 			if( !auth_http_is_logout_pending() ) {
+				if (isset($_SERVER['REMOTE_USER'])) {
+				    $f_password = '';
+				}
 
 				/* this will never get hit - see auth_prepare_username */
 				if( isset( $_SERVER['PHP_AUTH_PW'] ) ) {
@@ -260,7 +269,7 @@ function auth_attempt_login( $p_username, $p_password, $p_perm_login = false ) {
 	if( !user_is_anonymous( $t_user_id ) ) {
 		# anonymous login didn't work, so check the password
 
-		if( !auth_does_password_match( $t_user_id, $p_password ) ) {
+		if ( HTTP_AUTH != $t_login_method && !auth_does_password_match( $t_user_id, $p_password ) ) {
 			user_increment_failed_login_count( $t_user_id );
 			return false;
 		}
-- 
1.7.1

