Exemple #1
0
/**
 * Check username and password against RADIUS authentication backend.
 *
 * @param string $username User name to check
 * @param string $password User password to check
 * @return int Authentication success (0 = fail, 1 = success) FIXME bool
 */
function radius_authenticate($username, $password)
{
    global $config, $rad;
    radius_init();
    if ($username && $rad) {
        //print_vars(radius_server_secret($rad));
        radius_create_request($rad, RADIUS_ACCESS_REQUEST);
        radius_put_attr($rad, RADIUS_USER_NAME, $username);
        switch (strtolower($config['auth_radius_method'])) {
            // CHAP-MD5 see RFC1994
            case 'chap':
            case 'chap_md5':
                $chapid = 1;
                // Specify a CHAP identifier
                //$challenge = mt_rand(); // Generate a challenge
                //$cresponse = md5(pack('Ca*', $chapid, $password.$challenge), TRUE);
                new Crypt_CHAP();
                // Pre load class
                $crpt = new Crypt_CHAP_MD5();
                $crpt->password = $password;
                $challenge = $crpt->challenge;
                $resp_md5 = $crpt->challengeResponse();
                $resp = pack('C', $chapid) . $resp_md5;
                radius_put_attr($rad, RADIUS_CHAP_PASSWORD, $resp);
                // Add the Chap-Password attribute
                radius_put_attr($rad, RADIUS_CHAP_CHALLENGE, $challenge);
                // Add the Chap-Challenge attribute.
                break;
                // MS-CHAPv1 see RFC2433
            // MS-CHAPv1 see RFC2433
            case 'mschapv1':
                $chapid = 1;
                // Specify a CHAP identifier
                $flags = 1;
                // 0 = use LM-Response, 1 = use NT-Response (we not use old LM)
                new Crypt_CHAP();
                // Pre load class
                $crpt = new Crypt_CHAP_MSv1();
                $crpt->password = $password;
                $challenge = $crpt->challenge;
                $resp_lm = str_repeat("", 24);
                $resp_nt = $crpt->challengeResponse();
                $resp = pack('CC', $chapid, $flags) . $resp_lm . $resp_nt;
                radius_put_vendor_attr($rad, RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
                radius_put_vendor_attr($rad, RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $challenge);
                break;
                // MS-CHAPv2 see RFC2759
            // MS-CHAPv2 see RFC2759
            case 'mschapv2':
                $chapid = 1;
                // Specify a CHAP identifier
                $flags = 1;
                // 0 = use LM-Response, 1 = use NT-Response (we not use old LM)
                new Crypt_CHAP();
                // Pre load class
                $crpt = new Crypt_CHAP_MSv2();
                $crpt->username = $username;
                $crpt->password = $password;
                $challenge = $crpt->authChallenge;
                $challenge_p = $crpt->peerChallenge;
                $resp_nt = $crpt->challengeResponse();
                // Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response
                $resp = pack('CCa16a8a24', $chapid, $flags, $challenge_p, str_repeat("", 8), $resp_nt);
                radius_put_vendor_attr($rad, RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
                radius_put_vendor_attr($rad, RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $challenge);
                break;
                // PAP (Plaintext)
            // PAP (Plaintext)
            default:
                radius_put_attr($rad, RADIUS_USER_PASSWORD, $password);
        }
        // Puts standard attributes
        $radius_ip = get_ip_version($config['auth_radius_nas_address']) ? $config['auth_radius_nas_address'] : $_SERVER['SERVER_ADDR'];
        if (get_ip_version($radius_ip) == 6) {
            // FIXME, not sure that this work correctly
            radius_put_attr($rad, RADIUS_NAS_IPV6_ADDRESS, $radius_ip);
        } else {
            radius_put_addr($rad, RADIUS_NAS_IP_ADDRESS, $radius_ip);
        }
        $radius_id = empty($config['auth_radius_id']) ? get_localhost() : $config['auth_radius_id'];
        radius_put_attr($rad, RADIUS_NAS_IDENTIFIER, $radius_id);
        //radius_put_attr($rad, RADIUS_NAS_PORT_TYPE, RADIUS_VIRTUAL);
        //radius_put_attr($rad, RADIUS_SERVICE_TYPE, RADIUS_FRAMED);
        //radius_put_attr($rad, RADIUS_FRAMED_PROTOCOL, RADIUS_PPP);
        radius_put_attr($rad, RADIUS_CALLING_STATION_ID, isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1');
        $response = radius_send_request($rad);
        //print_vars($response);
        switch ($response) {
            case RADIUS_ACCESS_ACCEPT:
                // An Access-Accept response to an Access-Request indicating that the RADIUS server authenticated the user successfully.
                //echo 'Authentication successful';
                return 1;
                break;
            case RADIUS_ACCESS_REJECT:
                // An Access-Reject response to an Access-Request indicating that the RADIUS server could not authenticate the user.
                //echo 'Authentication failed';
                break;
            case RADIUS_ACCESS_CHALLENGE:
                // An Access-Challenge response to an Access-Request indicating that the RADIUS server requires further information
                // in another Access-Request before authenticating the user.
                //echo 'Challenge required';
                break;
            default:
                print_error('A RADIUS error has occurred: ' . radius_strerror($rad));
        }
    }
    //session_logout();
    return 0;
}
*/
if ($argv[1] == 'pearcvs') {
    ini_set('include_path', '..:' . ini_get('include_path'));
    require_once 'CHAP.php';
} else {
    require_once 'Crypt/CHAP.php';
}
echo "CHAP-MD5 TEST\n";
$crpt = new Crypt_CHAP_MD5();
$crpt->password = '******';
$crpt->chapid = 1;
$crpt->challenge = pack('H*', '102DB5DF085D3041');
printf("ChallResp : %s\nexpected  : 8f028814450d66d94c72331ef455a172\n", bin2hex($crpt->challengeResponse()));
echo "\n";
echo "CHAP-MD5 TEST 2\n";
$crpt = new Crypt_CHAP_MD5();
$crpt->password = '******';
$crpt->chapid = 1;
$crpt->challenge = pack('H*', '102DB5DF085D3041');
printf("ChallResp : %s\nexpected  : d39bfaf5d6855a948c8c81a85947502c\n", bin2hex($crpt->challengeResponse()));
echo "\n";
echo "MS-CHAPv1 str2unicode\n";
$crpt = new Crypt_CHAP_MSv1();
printf("Passed 123 as Number:%s\n", bin2hex($crpt->str2unicode(123)));
printf("Passed 123 as String:%s\n", bin2hex($crpt->str2unicode('123')));
echo "MS-CHAPv1 TEST\n";
$crpt->password = '******';
$crpt->challenge = pack('H*', '102DB5DF085D3041');
$unipw = $crpt->str2unicode($pass);
printf("Unicode PW: %s\nexpected  : 4d00790050007700\n", bin2hex($unipw));
printf("NT HASH   : %s\nexpected  : fc156af7edcd6c0edde3337d427f4eac\n", bin2hex($crpt->ntPasswordHash()));
 /**
  *  Check given credentials and return uid of user (string) if they are 
  *	correct. If credentials are wrong integer error code is returned:
  *		 0 - credentials can not be checked (radius error)
  *		-1 - this tripple (uname, realm, password) not exists
  *		-2 - this credentials is not for use in serweb
  *		-3 - account is disabled
  *		-4 - account is deleted
  *
  *  Possible options:
  *		none
  *
  *	@param string $uname	username
  *	@param string $did	    did
  *	@param string $realm	realm
  *	@param string $passw	password
  *	@param array $opt		associative array of options
  *	@return mixed			uid or error code
  */
 function check_credentials($uname, $did, $realm, $passw, $opt)
 {
     global $config, $lang_str;
     if ($config->clear_text_pw) {
         $rauth = new Serweb_Auth_RADIUS_PAP($uname . "@" . $realm, $passw);
     } else {
         $crpt = new Crypt_CHAP_MD5();
         $crpt->password = $passw;
         $rauth = new Serweb_Auth_RADIUS_CHAP_MD5($uname . "@" . $realm, $crpt->challenge, $crpt->chapid);
         $rauth->response = $crpt->challengeResponse();
         $rauth->flags = 1;
     }
     foreach ($config->auth_radius['host'] as $h) {
         $rauth->addServer($h['host'], $h['port'], $h['sharedsecret'], $h['timeout'], $h['maxtries']);
     }
     if (!$rauth->start()) {
         ErrorHandler::log_errors(PEAR::raiseError("Radius: " . $rauth->getError()));
         return false;
     }
     $result = $rauth->send();
     if (PEAR::isError($result)) {
         ErrorHandler::log_errors($result);
         return false;
     }
     if ($result !== true) {
         sw_log("Radius request rejected for user '" . $uname . "@" . $realm . "'", PEAR_LOG_INFO);
         return -1;
     }
     $rauth->getAttributes();
     if (!isset($rauth->attributes['ser-attrs']['uid'])) {
         sw_log("UID is not returned for user '" . $uname . "@" . $realm . "'", PEAR_LOG_INFO);
         return -1;
     }
     return $rauth->attributes['ser-attrs']['uid'];
 }