<?php

/*
 * postLdapAdmin
 *
 * Copyright (C) 2006,2007 DesigNET, INC.
 *
 * This program 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.

 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/***********************************************************
 * å饤֥
 *
 * $RCSfile: libsess,v $
 * $Revision: 1.20 $
 * $Date: 2009/06/12 06:02:30 $
 **********************************************************/

/*  */
define("SYSADM", -1);

/* ̥桼 */
define("GENUSER", 1);

/* å󥿥() */
define("SESSION_TIME", 900);

/***********************************************************
 * sess_start()
 *
 * å󳫻
 *
 * []
 *      $user           ̾
 *      $passwd         ѥ
 *      &$sess_key      å󥭡
 *      &$chk_mode      å⡼
 * [֤]
 *      TRUE            OK
 *      FALSE           NG
 **********************************************************/
function sess_start($user, $passwd, &$sess_key, &$chk_mode = SYSADM) {

    global $err_msg;
    global $env;

    /* 桼å */
    if (user_check($user, $passwd, $chk_mode) === FALSE) {
       return FALSE;
    }
    /* å󥭡 */
    if (sess_key_make($user, $passwd, $sess_key) === FALSE) {
       return FALSE;
    }

    /* 桼 */
    $env['loginuser'] = $user;

    return TRUE;
}

/***********************************************************
 * user_check()
 *
 * ȤΥѥɥå
 *
 * []
 *      $name           ̾ 
 *      $passwd         ѥ 
 *      &$limit         ͭ
 *      $chk_mode       å⡼
 * [֤]
 *      TRUE            OK
 *      FALSE           NG
 **********************************************************/
function user_check($name, $passwd, $chk_mode) {

    global $err_msg;
    global $web_conf;

    /* ̥桼å */
    if ($chk_mode === GENUSER) {
        return general_user_check($name, $passwd);
    }

    /* ԥå */
    if ($web_conf["adminname"] != $name) {
        return FALSE;
    }

    $mode = SYSADM;

    /* ǥɻ˥ѥɤ夹NULLڽ */
    $passwd = trim($passwd);

    /* ѥɥå */
    if (md5($passwd) != $web_conf["adminpasswd"]) {
        $err_msg = "桼̾⤷ϥѥɤְäƤޤ";
        return FALSE;
    }

    return TRUE;
}

/***********************************************************
 * sess_key_make()
 * 
 * å󥭡
 *
 * []
 *      $user         桼ID
 *      $passwd       ѥ
 *      &$sess_key    å󥭡
 * [֤]
 *      TRUE          
 *      FALSE         顼
 **********************************************************/
function sess_key_make ($user, $passwd, &$sess_key)
{
    global $err_msg;

    /* adminɹ */
    if (admin_key_read($akey) === FALSE) {
        return FALSE;
    }
    /* Ź沽ʸ */
    $input = sprintf("%s:%s:%s", time() + SESSION_TIME, $user, $passwd);

    /* Ź沽 */
    srand();
    $td = mcrypt_module_open (MCRYPT_3DES, "", MCRYPT_MODE_CBC, "");
    $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    $encrypted_data = mcrypt_encrypt(MCRYPT_3DES, $akey, $input,
                                                         MCRYPT_MODE_CBC, $iv);
    /* Ϥѥ󥳡 */
    $sess_key = base64_encode($iv . $encrypted_data);

    return TRUE;
}

/***********************************************************
 * sess_key_decode()
 *
 * å󥭡椹
 *
 * []
 *       $sess_key  å󥭡
 *       &$dec_key  ǥɤå󥭡
 * [֤]
 *       TRUE       
 *       FALSE      顼
 **********************************************************/
function sess_key_decode($sess_key, &$dec_key) 
{
    global $err_msg;

    # adminɹ
    if (admin_key_read($akey) === FALSE) {
        return FALSE;
    }

    # ʣ粽
    $td = mcrypt_module_open (MCRYPT_3DES, "", MCRYPT_MODE_CBC, "");
    $ivlen = mcrypt_enc_get_iv_size($td);

    # ʸѴ
    $d64 = base64_decode($sess_key);

    #
    $iv = substr($d64, 0, $ivlen);
    $decode =  substr($d64, $ivlen);

    # ʣ粽
    $tmp = @mcrypt_decrypt(MCRYPT_3DES, $akey, $decode, MCRYPT_MODE_CBC, $iv);

    # ԡ
    $dec_key = $tmp;

    return TRUE;
}

/***********************************************************
 * admin_key_read()
 *
 * admin.keyɤ߹
 *
 * []
 *       $akey    admin.keyΰ
 * [֤]
 *       TRUE     
 *       FALSE    顼
 **********************************************************/
function admin_key_read (&$akey)
{
    global $err_msg;
    global $admkey_file;

    # adminΥå
    if (is_readable_file($admkey_file) === FALSE) {
        $err_msg = "Ź沽" . $err_msg;
        return FALSE;
    }
    # Ź沽եΥץ
    $tmp = file ($admkey_file);

    # å
    if ($tmp === FALSE) {
        $err_msg = "Ź沽ե뤬ץǤޤ(" . $admkey_file . ")";
        return FALSE;
    }

    # եƥå
    if (is_null($tmp[0]) === TRUE) {
        $err_msg = "Ź沽ե뤬ޤ(" . $admkey_file . ")";
        return FALSE;
    }

    # üβԤƳǼ
    $akey = rtrim($tmp[0]);

    return TRUE;
}


/***********************************************************
 * sess_logout()
 *
 * 
 *
 * []
 *      $sess_key       å󥭡
 * [֤]
 *      TRUE            OK
 **********************************************************/
function sess_logout($sess_key) {

    global $err_msg;
    global $env;

    if ($sess_key == "") {
        return TRUE;
    }

    /* ǥ */
    if (sess_key_decode($sess_key, $dec_key) === FALSE) {
        return TRUE;
    }

    /* ʬ */
    list($time, $user, $passwd) = explode(':', $dec_key, 3);

    /* 桼 */
    $env['loginuser'] = $user;
    $env['loginpasswd'] = $passwd;

    return TRUE;
}

/***********************************************************
 * sess_check()
 *
 * åǧ
 *
 * []
 *      $sess_key 	å󥭡
 *      $chk_mode	ø
 * [֤]
 *      TRUE            OK
 *      FALSE           NG
 ************************************************************/
function sess_check (&$sess_key, $chk_mode)
{
    global $err_msg;
    global $env;
    global $web_conf;

    /* եʸ */
    $len = strlen($web_conf["referrerurl"]);

    /* եΥå */
    if (strncmp($web_conf["referrerurl"],
                          $_SERVER["HTTP_REFERER"], $len) != 0) {
        $err_msg = "åͭǤϤޤ";
        return FALSE;
    }

    /* å󥭡NULLå */
    if (is_null($sess_key) === TRUE) {
        $err_msg = "åͭǤϤޤ";
        return FALSE;
    }

    /* å󥭡ǥɤ */
    if (sess_key_decode($sess_key, $dec_key) === FALSE) {
        return FALSE;
    }

    list($time, $user, $passwd) = explode(':', $dec_key, 3);
    if (is_null($time) === TRUE || is_null($user) === TRUE || 
        is_null($passwd) === TRUE) {
        $err_msg = "åͭǤϤޤ";
        return FALSE;
    }

    /* 桼 */
    $env['loginuser'] = $user;

    /* ȤΥå */
    if (user_check($user, $passwd, $chk_mode) === FALSE) {
        return FALSE;
    }

    /* å󥿥Υå */
    if ($time < time()) {
        return FALSE;
    }

    /* å󥭡򹹿 */
    if (sess_key_make($user, $passwd, $sess_key) === FALSE) {
       return FALSE;
    }


    return TRUE;
}

/***********************************************************
 * is_sysadm()
 *
 * ƥѥåå
 *
 * []
 *      $sess_key       å󥭡
 * [֤]
 *      TRUE            OK
 *      FALSE           NG
 ************************************************************/
function is_sysadm (&$sess_key)
{
    # ƥ
    return sess_check ($sess_key, SYSADM);
}

/***********************************************************
 * general_user_check()
 *
 * ̥桼ѥɥå
 * []
 *      $name           桼̾ 
 *      $passwd         ѥ 
 * [֤]
 *      TRUE            OK
 *      FALSE           NG
 **********************************************************/
function general_user_check($name, $passwd) {

    global $err_msg;
    global $web_conf;
    global $env;

    $result = array();
    $attrs = array();
    $lfilter = mk_filter($name);
    $ret = main_get_entry($web_conf["ldapusersuffix"] . "," . $web_conf["ldapbasedn"],
                   $lfilter,
                   $attrs,
                   $web_conf["ldapscope"],
                   $result);
    if ($ret != LDAP_OK) {
        return FALSE;
    }

    $env["user_self"] = TRUE;
    $env["user_selfdn"] = $result[0]["dn"];
    $env["user_selfpw"] = $passwd;

    /* ѥɥå(LDAPХ) */
    $ds = LDAP_connect_server();
    if ($ds == LDAP_ERR_BIND) {
        return FALSE;
    }
    ldap_unbind($ds);

    return TRUE;
}

/***********************************************************
 * is_user()
 *
 * 桼ѥåå
 *
 * []
 *      $sess_key     å󥭡
 * [֤]
 *      TRUE          OK
 *      FALSE         NG
 ************************************************************/
function is_user (&$sess_key)
{
    /* ̥桼 */
    return sess_check ($sess_key, GENUSER);
}

?>
