<?php
/*******************************************************************************
 *
 * LEIDEN OPEN VARIATION DATABASE (LOVD)
 *
 * Created     : 2006-04-21
 * Modified    : 2009-10-29
 * For LOVD    : 2.0-23
 *
 * Access      : Public
 * Purpose     : Log in the user, whether that's a submitter or a
 *               manager/administrator.
 *
 * Copyright   : 2004-2009 Leiden University Medical Center; http://www.LUMC.nl/
 * Programmer  : Ing. Ivo F.A.C. Fokkema <I.F.A.C.Fokkema@LUMC.nl>
 * Last edited : Ing. Ivo F.A.C. Fokkema <I.F.A.C.Fokkema@LUMC.nl>
 *
 *
 * This file is part of LOVD.
 *
 * LOVD is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * LOVD is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LOVD; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *************/

define('ROOT_PATH', './');
require ROOT_PATH . 'inc-init.php';

// Already logged in to the system.
if ($_AUTH) {
    // Send manager and database administrator to setup, curators and submitters to the index.
    header('Location: ' . PROTOCOL . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/') . '/' . (HAS_AUTH? 'config' : 'index') . '.php' . lovd_showSID());
    exit;
}

require ROOT_PATH . 'inc-lib-form.php';
lovd_errorClean();

// 2008-11-25; 2.0-14; Restructure login procedure.
// 2009-06-22; 2.0-19; Only force use of cookies, when cookies are requested!
if (!isset($_COOKIE['lovd_cookie_check']) && !empty($_CONF['use_cookies'])) {
    lovd_errorAdd('Cookies must be enabled before you can log in. Please enable cookies or lower your browser\'s security settings.');

} else {
    // 2008-11-25; 2.0-14; We're now also accepting unlocking accounts.
    if (isset($_GET['sent']) && isset($_POST['username'], $_POST['password'])) {
        // First, retrieve account information.
        $zUser = mysql_fetch_assoc(mysql_query('SELECT * FROM ' . TABLE_SUBS . ' WHERE username = "' . $_POST['username'] . '" AND deleted = 0'));
        if (!$zUser) {
            $zUser = mysql_fetch_assoc(mysql_query('SELECT * FROM ' . TABLE_USERS . ' WHERE username = "' . $_POST['username'] . '" AND deleted = 0'));
        }



        // 2008-11-25; 2.0-14; Allow account unlocking.
        if ($zUser && $_CONF['allow_unlock'] && $zUser['password_autogen'] && $zUser['password_autogen'] == md5($_POST['password'])) {
            // Successfully unlocking an account! Log user in.

            if (isset($zUser['submitterid'])) {
                $_SESSION['subs'] = $zUser;
                $_SUBS = & $_SESSION['subs'];
                $_AUTH = & $_SUBS;
            } else {
                $_SESSION['auth'] = $zUser;
                $_AUTH = & $_SESSION['auth'];
            }

            lovd_writeLog('MySQL:Auth', 'AuthLogin', $_SERVER['REMOTE_ADDR'] . ' (' . gethostbyaddr($_SERVER['REMOTE_ADDR']) . ') successfully logged in using ' . $_POST['username'] . '/unlocking code');
            $_SESSION['last_login'] = $_AUTH['last_login'];
            // 2008-08-28; 2.0-11; Protect against Session Fixation.
            // 2009-10-29; 2.0-23; #45; Exclude this part of code for PHP versions < 4.3.10.
            if (!(substr(phpversion(), 0, 4) == '4.3.' && substr(phpversion(), 4) < 10) && function_exists('session_regenerate_id')) {
                session_regenerate_id();
                // 2008-09-02; 2.0-11 update; Fix weird behaviour of session_regenerate_id() - sometimes it was not sending a new cookie.
                setcookie(session_name(), session_id(), ini_get('session.cookie_lifetime'));
            }
            // Also update the password field, it needs to be used by the update password form.
            mysql_query('UPDATE ' . ($_SUBS? TABLE_SUBS : TABLE_USERS) . ' SET password = MD5("' . $_POST['password'] . '"), ' . ($_SUBS? '' : 'phpsessid = "' . session_id() . '", ') . 'last_login = NOW(), login_attempts = 0 WHERE ' . ($_SUBS? 'submitterid = "' . $_SUBS['submitterid'] : 'userid = "' . $_AUTH['userid']) . '"');
            $_AUTH['password'] = md5($_POST['password']);

            // Since this is the unlocking code, the user should be forced to change his/her password.
            $_SESSION['password_force_change'] = true;

            header('Location: ' . PROTOCOL . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/') . '/' . ROOT_PATH . 'account_update.php?action=change_passwd' . lovd_showSID(true));
            exit;
        }



        // Next, check if the account is locked.
        if ($zUser && $zUser['login_attempts'] >= 3) {
            // Account is locked!

            // Show login form.
            unset($zUser);

            // Spit out error.
            lovd_errorAdd('Your account is locked, usually because a wrong password was provided three times. Please contact a LOVD manager or the database administrator to unlock your account.');
        }



        // Finally, log in user if the correct password has been given.
        if (!empty($zUser) && $zUser['password'] == md5($_POST['password'])) {
            // Successfully logging in!

            if (isset($zUser['submitterid'])) {
                $_SESSION['subs'] = $zUser;
                $_SUBS = & $_SESSION['subs'];
                $_AUTH = & $_SUBS;
            } else {
                $_SESSION['auth'] = $zUser;
                $_AUTH = & $_SESSION['auth'];
            }



            lovd_writeLog('MySQL:Auth', 'AuthLogin', $_SERVER['REMOTE_ADDR'] . ' (' . gethostbyaddr($_SERVER['REMOTE_ADDR']) . ') successfully logged in using ' . $_POST['username'] . '/' . str_repeat('*', strlen($_POST['password'])));
            $_SESSION['last_login'] = $_AUTH['last_login'];
            // 2008-08-28; 2.0-11; Protect against Session Fixation.
            // 2009-10-29; 2.0-23; #45; Exclude this part of code for PHP versions < 4.3.10.
            if (!(substr(phpversion(), 0, 4) == '4.3.' && substr(phpversion(), 4) < 10) && function_exists('session_regenerate_id')) {
                session_regenerate_id();
                // 2008-09-02; 2.0-11 update; Fix weird behaviour of session_regenerate_id() - sometimes it was not sending a new cookie.
                setcookie(session_name(), session_id(), ini_get('session.cookie_lifetime'));
            }
            mysql_query('UPDATE ' . ($_SUBS? TABLE_SUBS : TABLE_USERS) . ' SET password_autogen = "", ' . ($_SUBS? '' : 'phpsessid = "' . session_id() . '", ') . 'last_login = NOW(), login_attempts = 0 WHERE ' . ($_SUBS? 'submitterid = "' . $_SUBS['submitterid'] : 'userid = "' . $_AUTH['userid']) . '"');

            // 2008-11-21; 2.0-14; Check if the user should be forced to change his/her password.
            if (!empty($_AUTH['password_force_change'])) {
                $_SESSION['password_force_change'] = true;
            }

            header('Location: ' . PROTOCOL . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . lovd_showSID());
            exit;



        // Not the locked accounts, only the bad logins.
        } elseif (isset($zUser)) {
            lovd_writeLog('MySQL:Auth', 'AuthError', $_SERVER['REMOTE_ADDR'] . ' (' . gethostbyaddr($_SERVER['REMOTE_ADDR']) . ') tried logging in using ' . $_POST['username'] . '/' . str_repeat('*', strlen($_POST['password'])));
            lovd_errorAdd('Invalid Username/Password combination.');

            // This may not actually update (user misspelled his username) but we can call the query anyway.
            if ($_CONF['lock_submitters']) {
                mysql_query('UPDATE ' . TABLE_SUBS . ' SET login_attempts = login_attempts + 1 WHERE username = "' . $_POST['username'] . '" AND deleted = 0');
            }
            if ($_CONF['lock_curators']) {
                mysql_query('UPDATE ' . TABLE_USERS . ' SET login_attempts = login_attempts + 1 WHERE username = "' . $_POST['username'] . '" AND level < 9 AND deleted = 0');
            }

            // Check if the user is locked, now.
            if (is_array($zUser) && $zUser['login_attempts'] >= (3-1)) {
                lovd_errorAdd('Your account is now locked, since this is the third time a wrong password was provided.');
            }

            // 2008-11-26; 2.0-14; Add "Forgot my password" option.
            if ($_CONF['allow_unlock']) {
                lovd_errorAdd('Did you <A href="' . ROOT_PATH . 'account_update.php?action=reset_passwd">forget your password</A>?');
            }
        }
    }

    // Clean up after ourselves.
    unset($zUser);
}



if (!$_AUTH) {
    require ROOT_PATH . 'inc-top.php';
    lovd_printHeader('account_login', 'Account - Log in');

    lovd_errorPrint();

    print('      <FORM action="' . $_SERVER['PHP_SELF'] . '?sent" method="post">
    <TABLE border="0" cellpadding="0" cellspacing="0" width="300">
      <TR align="right">
        <TD width="125" style="padding-right : 5px;">Username</TD>
        <TD width="175"><INPUT type="text" name="username" size="20"></TD></TR>
      <TR>
        <TD colspan="2"><IMG src="gfx/trans.png" alt="" width="1" height="1"></TD></TR>
      <TR align="right">
        <TD width="125" style="padding-right : 5px;">Password</TD>
        <TD width="175"><INPUT type="password" name="password" size="20"></TD></TR>
      <TR>
        <TD colspan="2"><IMG src="gfx/trans.png" alt="" width="1" height="1"></TD></TR>
      <TR align="right">
        <TD width="125">&nbsp;</TD>
        <TD width="175"><INPUT type="submit" value="Log in"></TD></TR></TABLE>
  </FORM>

  <SCRIPT type="text/javascript">
    document.forms[0].username.focus();
  </SCRIPT>' . "\n\n");

    require ROOT_PATH . 'inc-bot.php';
    exit;
}
?>
