<?php
    /*
     * $Id: xlogin.php 1502 2011-01-08 21:10:00Z dmorton $
     *
     * MAIA MAILGUARD LICENSE v.1.0
     *
     * Copyright 2004 by Robert LeBlanc <rjl@renaissoft.com>
     *               and David Morton   <mortonda@dgrmm.net>
     * All rights reserved.
     *
     * PREAMBLE
     *
     * This License is designed for users of Maia Mailguard
     * ("the Software") who wish to support the Maia Mailguard project by
     * leaving "Maia Mailguard" branding information in the HTML output
     * of the pages generated by the Software, and providing links back
     * to the Maia Mailguard home page.  Users who wish to remove this
     * branding information should contact the copyright owner to obtain
     * a Rebranding License.
     *
     * DEFINITION OF TERMS
     *
     * The "Software" refers to Maia Mailguard, including all of the
     * associated PHP, Perl, and SQL scripts, documentation files, graphic
     * icons and logo images.
     *
     * GRANT OF LICENSE
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * 3. The end-user documentation included with the redistribution, if
     *    any, must include the following acknowledgment:
     *
     *    "This product includes software developed by Robert LeBlanc
     *    <rjl@renaissoft.com>."
     *
     *    Alternately, this acknowledgment may appear in the software itself,
     *    if and wherever such third-party acknowledgments normally appear.
     *
     * 4. At least one of the following branding conventions must be used:
     *
     *    a. The Maia Mailguard logo appears in the page-top banner of
     *       all HTML output pages in an unmodified form, and links
     *       directly to the Maia Mailguard home page; or
     *
     *    b. The "Powered by Maia Mailguard" graphic appears in the HTML
     *       output of all gateway pages that lead to this software,
     *       linking directly to the Maia Mailguard home page; or
     *
     *    c. A separate Rebranding License is obtained from the copyright
     *       owner, exempting the Licensee from 4(a) and 4(b), subject to
     *       the additional conditions laid out in that license document.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
     * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */

   require_once ("core.php");
   require_once ("auth.php");
   require_once ("maia_db.php");
   require_once ("mailtools.php");
   
   $uid = 0;
   $euid = 0;
   $msid = "";
   $sid = ""; 

   // Get the expected form variables from the POST array
   if (isset($_POST["language"])   && strlen($_POST["language"]) == 2 ) {
      $display_language = trim($_POST["language"]);
   } else {
      $display_language = $default_display_language;
   }
   if (isset($_POST["offset"]) && is_numeric($_POST["offset"])) {
      $clock_offset = intval($_POST["offset"]);
   } else {
      $clock_offset = 0;
   }

   require_once ("./locale/$display_language/auth.php");
   require_once ("./locale/$display_language/db.php");
   require_once ("./locale/$display_language/display.php");
   require_once ("./locale/$display_language/login.php");
   require_once ("./locale/$display_language/xlogin.php");
   require_once ("./locale/$display_language/errors.php");


   if (isset($_POST["username"])) {
      $user_name = trim($_POST["username"]);
   } else {
      $user_name = "";
   }
   if (isset($_POST["pwd"])) {
      $pwd = trim($_POST["pwd"]);
      $pwd = stripslashes($pwd); // get rid of any escape characters
   } else {
      $pwd = "";
   }
   if (isset($_POST["domain"])) {
      $nt_domain = trim($_POST["domain"]);
   } else {
      $nt_domain = "";
   }
   if (isset($_POST["address"])) {
      $address = trim($_POST["address"]);
   } else {
      $address = "";
   }
   if (isset($_POST["super"])) {
      $super = trim($_POST["super"]);
   } else {
      $super = "";
   }
   
   //we want to weed out linked emails during the login process, as it can result in security issues
   // and also db corruption, see ticket #427
   function is_primary_email($email)
   {
       global $dbh;

       $email_id = 0;
       $select = "SELECT users.id FROM users left join maia_users ON users.maia_user_id=maia_users.id WHERE maia_users.primary_email_id <> users.id and users.email = ?";
       $sth = $dbh->query($select, array($email));
       if ($row = $sth->fetchrow()) {
           $email_id = $row["id"];
       }
       $sth->free();

       return $email_id == 0 ? true : false;
   }

   if (isset($_GET["token"]) &&
       isset($_GET["id"])    &&
       isset($_GET["euid"])  &&
       isset($_GET["action"])) {
      //we are not entering by way of login form, but by way of special token.
      $token = trim($_GET['token']);
      $user_token = trim($_GET['user_token']);
      $maia_user_id = trim($_GET['id']);
      $euid = trim($_GET['euid']);
      $action = trim($_GET['action']);

      if ($action == "view.php" || $action == "rescue.php") {
          $select = "SELECT recipient_id FROM maia_mail_recipients " .
                    "WHERE recipient_id=? " .
                    "AND token=?";
          $sth = $dbh->query($select, array($euid,$token));
          if ($row = $sth->fetchrow()) {
             $select = "SELECT data FROM maia_tokens " .
                        "WHERE data=? " .
                        "AND token=? " .
                        "AND token_system='digest'" ;
              $sth = $dbh->query($select, array($maia_user_id,$user_token));
              if ($row = $sth->fetchrow()) {
                $uid = $maia_user_id;
                $authenticated = true;
              } else {
                $authenticated = PEAR::raiseError($lang['invalid_token']);
              }
          } else {
            $authenticated = PEAR::raiseError($lang['invalid_token']);
          }
      } elseif ($action == "confirm.php") {
          $select = "SELECT data FROM maia_tokens " .
                    "WHERE data=? " .
                    "AND token=? " .
                    "AND token_system='digest'" ;
          $sth = $dbh->query($select, array($maia_user_id,$token));
          if ($row = $sth->fetchrow()) {
            $uid = $maia_user_id;
            $authenticated = true;
          } else {
            $logger->err("token or data not found");
            $authenticated = PEAR::raiseError($lang['invalid_token']);
          }

      } else {
         $logger->err("unknown action");
         $authenticated = PEAR::raiseError($lang['invalid_token']);
      }
      if (! ok_to_impersonate($euid, $uid)) {
        $logger->err("user $uid cannot impersonate $euid");
        $authenticated = PEAR::raiseError($lang['invalid_token']);
      }

   } else {
      if ($auth_method == "imap") {
          $imap_address = get_rewritten_email_address($address, $address_rewriting_type);
          $user_name = get_user_from_email($imap_address);
      } elseif ($auth_method == "pop3" && empty($routing_domain)) {
          $user_name = get_user_from_email($address);
      } elseif ($auth_method == "external") {
            $user_name = ereg_replace('@.*$','',$user_name);
            // FIXME there has to be a better way to do this. It implements the
            // assumption (valid here) that the LHS of all addresses that need to
            // be authenticated against is the user name.  But some things just didn't
            // work right until I added this code.
      }

      list($authenticated, $email) = auth($user_name, $pwd, $address, $nt_domain);
      if ($authenticated === true) {
        if (is_primary_email($email)) {
          $owner_id = get_email_address_owner(get_email_address_id($email));
          $uid = get_user_id($user_name, $email);
          if ($owner_id != 0 && $owner_id != $uid) {
            $authenticated = PEAR::raiseError($lang['error_case_mixup_rejected_html']);
            $logger->warning(sprintf($lang['error_case_mixup_rejected_log'], $email, $address, $user_name, $uid, $owner_id));
          }
        } else {
            $authenticated = PEAR::raiseError(sprintf($lang['error_link_login_failed'], $email));
            $logger->warning(sprintf($lang['error_link_login_failed'], $email));
        }  
          
      }
    
   }
   if ($authenticated === true)
   {
       session_start();
       session_unset(); // clear any session data

       // See if this user has an entry in the users table yet
       // and if not, create one for him (with default values).
       if ($uid == 0) {
           $uid = add_user($user_name, $email);
         $_SESSION["firsttime"] = true;
       }

       if ($euid == 0) {
         $euid = $uid;
       }

       $_SESSION["timeout"] = time() + $default_session_timeout * 60;

       $_SESSION["clock_offset"] = $clock_offset;
       
       // Set session variables
       $_SESSION["uid"] = $uid;
       $_SESSION["euid"] = $euid;
       
       // set up language preferences
       $_SESSION["display_language"] = isset($_POST["language"]) ?
                                          trim($_POST["language"]) :
                                          get_display_language($euid);

       // If the $super variable was set, try to process the
       // (supposed) superuser's request.
       if ($super == "register") {
           if (get_superadmin_id() == 0) {
               set_superadmin_id($uid);
   	   }
       } elseif ($super == "unregister") {
           if (is_superadmin($uid)) {
               unset_superadmin_id($uid);
           }
       }

       // First time through, we don't know whether the user's
       // browser accepts cookies, so we include the session ID
       // in the GET just in case.
       header('Location: index.php?' . session_name() . '=' . session_id() . '&' . $_SERVER['QUERY_STRING']);
       exit();
   } else {
       $uid = 0;
       $euid = 0;
       $sid = "";
   }

   if (PEAR::isError($authenticated)) {
    $message = $authenticated->getMessage();
   }
   
   require_once ("smarty.php");  // register smarty *after* uid's are set

   
   
   $admin_email = get_config_value("admin_email");
   $admin_link = "<a href=\"mailto:" . $admin_email . "\">" . $admin_email . "</a>";
   
   $lang['text_login_failed1'] = sprintf($lang['text_login_failed1'], htmlentities($user_name));
   $lang['text_login_failed3'] = sprintf($lang['text_login_failed3'], $admin_link);

   $smarty->assign('lang', $lang);
   
   $smarty->display('xlogin.tpl');
   
?>
