client/manager/server: finish LDAP support

- get_project_config.php: if project supports LDAP,
  advertise this to the client.
- Manager: if project supports LDAP, say "Email address or LDAP ID"
  in Attach Project wizard,
  and don't do email address validation.
- lookup_account GUI RPC (client side): if passing an LDAP ID,
  don't lowercase it, and don't hash passwd
- lookup_account GUI RPC (server side): if passing an LDAP ID,
  pass appropriate URL args to Web RPC
- lookup_account Web RPC: in LDAP case, pass "ldap_auth" arg,
  and pass "ldap_uid" and "passwd".
  Handle these appropriately.
This commit is contained in:
David Anderson 2014-10-18 23:53:27 -07:00
parent 109f8a7463
commit d0fb0184e8
7 changed files with 113 additions and 50 deletions

View File

@ -132,16 +132,31 @@ int LOOKUP_ACCOUNT_OP::do_rpc(ACCOUNT_IN& ai) {
url = ai.url;
canonicalize_master_url(url);
url += "lookup_account.php";
url += "lookup_account.php?email_addr=";
parameter = ai.email_addr;
escape_url(parameter);
url += parameter;
if (strchr(ai.email_addr.c_str(), '@')) {
url += "?email_addr=";
parameter = ai.email_addr;
escape_url(parameter);
url += parameter;
url += "&passwd_hash=";
parameter = ai.passwd_hash;
escape_url(parameter);
url += parameter;
url += "&passwd_hash=";
parameter = ai.passwd_hash;
escape_url(parameter);
url += parameter;
} else {
// LDAP case
//
url += "?ldap_auth=1&ldap_uid=";
parameter = ai.email_addr;
escape_url(parameter);
url += parameter;
url += "&passwd=";
parameter = ai.passwd_hash;
escape_url(parameter);
url += parameter;
}
retval = gui_http->do_rpc(
this, url.c_str(), LOOKUP_ACCOUNT_FILENAME, false

View File

@ -492,9 +492,11 @@ void CAccountInfoPage::OnPageChanged( wxWizardExEvent& event ) {
}
}
m_pAccountEmailAddressCtrl->SetValidator(
CValidateEmailAddress(&m_strAccountEmailAddress)
);
if (!pc.ldap_auth) {
m_pAccountEmailAddressCtrl->SetValidator(
CValidateEmailAddress(&m_strAccountEmailAddress)
);
}
m_pAccountUsernameCtrl->SetValidator(
wxTextValidator(wxFILTER_NONE, &m_strAccountUsername)
);
@ -504,9 +506,15 @@ void CAccountInfoPage::OnPageChanged( wxWizardExEvent& event ) {
m_pAccountUsernameStaticCtrl->Hide();
m_pAccountUsernameCtrl->Hide();
m_pAccountEmailAddressStaticCtrl->SetLabel(
_("&Email address:")
);
if (pc.ldap_auth) {
m_pAccountEmailAddressStaticCtrl->SetLabel(
_("&Email address or LDAP ID:")
);
} else {
m_pAccountEmailAddressStaticCtrl->SetLabel(
_("&Email address:")
);
}
m_pAccountEmailAddressCtrl->SetValue(m_strAccountEmailAddress);
}

View File

@ -107,6 +107,10 @@ if (file_exists($tou_file)) {
}
}
if (LDAP_HOST) {
echo "<ldap_auth/>\n";
}
echo "</project_config>";
?>

View File

@ -22,45 +22,66 @@ require_once("../inc/boinc_db.inc");
require_once("../inc/util.inc");
require_once("../inc/email.inc");
require_once("../inc/xml.inc");
require_once("../inc/ldap.inc");
xml_header();
$retval = db_init_xml();
if ($retval) xml_error($retval);
$email_addr = get_str("email_addr");
$passwd_hash = get_str("passwd_hash", true);
$ldap_auth = get_str("ldap_auth", true);
$email_addr = BoincDb::escape_string($email_addr);
$user = BoincUser::lookup("email_addr='$email_addr'");
if (!$user) {
xml_error(ERR_DB_NOT_FOUND);
}
if (!$passwd_hash) {
echo "<account_out>
<success/>
</account_out>
";
exit();
}
$auth_hash = md5($user->authenticator.$user->email_addr);
// if no password set, set password to account key
//
if (!strlen($user->passwd_hash)) {
$user->passwd_hash = $auth_hash;
$user->update("passwd_hash='$user->passwd_hash'");
}
// if the given password hash matches (auth+email), accept it
//
if ($user->passwd_hash == $passwd_hash || $auth_hash == $passwd_hash) {
echo "<account_out>\n";
echo "<authenticator>$user->authenticator</authenticator>\n";
echo "</account_out>\n";
if (LDAP_HOST && $ldap_auth) {
// LDAP case.
//
$ldap_uid = get_str("ldap_uid");
$passwd = get_str("passwd");
list ($ldap_user, $error_msg) = ldap_auth($ldap_uid, $passwd);
if ($error_msg) {
xml_error(ERR_BAD_USER_NAME, $error_msg);
}
$x = ldap_email_string($ldap_uid);
$user = BoincUser::lookup_email_addr($x);
if (!$user) {
$user = make_user_ldap($x, $ldap_user->name);
if (!$user) {
xml_error(-1, "user record creation failed");
}
}
} else {
xml_error(ERR_BAD_PASSWD);
}
// normal (non-LDAP) case
$email_addr = get_str("email_addr");
$passwd_hash = get_str("passwd_hash", true);
$email_addr = BoincDb::escape_string($email_addr);
$user = BoincUser::lookup("email_addr='$email_addr'");
if (!$user) {
xml_error(ERR_DB_NOT_FOUND);
}
if (!$passwd_hash) {
echo "<account_out>\n";
echo " <success/>\n";
echo "</account_out>\n";
exit();
}
$auth_hash = md5($user->authenticator.$user->email_addr);
// if no password set, set password to account key
//
if (!strlen($user->passwd_hash)) {
$user->passwd_hash = $auth_hash;
$user->update("passwd_hash='$user->passwd_hash'");
}
// if the given password hash matches (auth+email), accept it
//
if ($user->passwd_hash == $passwd_hash || $auth_hash == $passwd_hash) {
echo "<account_out>\n";
echo "<authenticator>$user->authenticator</authenticator>\n";
echo "</account_out>\n";
} else {
xml_error(ERR_BAD_PASSWD);
}
}
?>

View File

@ -559,6 +559,8 @@ struct PROJECT_CONFIG {
// before allowing attachment to continue.
std::vector<std::string> platforms;
// platforms supported by project, or empty
bool ldap_auth;
// project supports LDAP authentication
PROJECT_CONFIG();
~PROJECT_CONFIG();
@ -572,7 +574,7 @@ struct ACCOUNT_IN {
std::string url;
// URL prefix for web RPCs
std::string email_addr;
// the account identifier (email address or user name)
// the account identifier (email address, user name, or LDAP uid)
std::string user_name;
std::string passwd;
std::string team_name;

View File

@ -2303,9 +2303,16 @@ int RPC_CLIENT::lookup_account(ACCOUNT_IN& ai) {
SET_LOCALE sl;
char buf[1024];
RPC rpc(this);
string passwd_hash;
downcase_string(ai.email_addr);
string passwd_hash = get_passwd_hash(ai.passwd, ai.email_addr);
if (strchr(ai.email_addr.c_str(), '@')) {
downcase_string(ai.email_addr);
passwd_hash = get_passwd_hash(ai.passwd, ai.email_addr);
} else {
// LDAP case
//
passwd_hash = ai.passwd;
}
snprintf(buf, sizeof(buf),
"<lookup_account>\n"
" <url>%s</url>\n"

View File

@ -77,6 +77,12 @@ MODE_BLANKSCREEN = 4
MODE_REREAD_PREFS = 5
MODE_QUIT = 6
NGRAPHICS_MSGS = 7
PROCESS_PRIORITY_UNSPECIFIED = 0
PROCESS_PRIORITY_LOWEST = 1
PROCESS_PRIORITY_LOW = 2
PROCESS_PRIORITY_NORMAL = 3
PROCESS_PRIORITY_HIGH = 4
PROCESS_PRIORITY_HIGHEST = 5
MSG_INFO = 1
MSG_USER_ALERT = 2
MSG_INTERNAL_ERROR = 3