суть: есть freeRadius + железка, которая авторизует клиента по средствам www странички, которая лежит на этой железке. надо сделать страницу, которая будет проводит авторизацию сама находясь локально с freeRadius сервером и слать сигнал на железку пропустить пользователя.решение: найден такой скрипт http://www.mavetju.org/programming/php.php, добпый человек поделился со всеми. Оказалось, что эксперементальные php функции socket_fd_alloc(); socket_fd_zero(); socket_fd_set(); вычеркнуты из php5. Далее был найден документ на финском из которого был взят тот же файл radius_authentication.inc, но уже под php5.
единственное изменение которое я заметил - это закоментированные socket_fd функции. вот сам файл:
<?php
// radius authentication v1.0 by Edwin Groothuis (edwin@mavetju.org)
function init_radiusconfig(&$server,&$port,&$sharedsecret,&$suffix) {
$file=fopen("./radius_authentication.conf","r");
if ($file==0) {
echo "Couldn't open radius_authentication.conf, exiting";
exit(0);
}
while (!feof($file)) {
$s=fgets($file,1024);
$s=chop($s);
if ($s[0]=="#") continue;
if (strlen($s)==0) continue;
if (preg_match("/^([a-zA-Z]+) (.*)$/",$s,$a)) {
if ($a[1]=="port") { $port=$a[2];continue; }
if ($a[1]=="server") { $server=$a[2];continue; }
if ($a[1]=="secret") { $sharedsecret=$a[2];continue; }
if ($a[1]=="suffix") {
$suffix=$a[2];
if ($suffix=="\"\"") {
$suffix="";
}
continue;
}
}
echo "Unknown config-file option: $a[1] ($s)\n";
exit(0);
}
fclose($file);
}
function RADIUS_AUTHENTICATION($username,$password) {
global $debug;
global $SERVER_ADDR;
$radiushost="";
$sharedsecret="";
$suffix="";
init_radiusconfig(&$radiushost,&$radiusport,&$sharedsecret,&$suffix);
// check your /etc/services. Some radius servers
// listen on port 1812, some on 1645.
if ($radiusport==0)
$radiusport=getservbyname("radius","udp");
$nasIP=explode(".",$SERVER_ADDR);
$ip=gethostbyname($radiushost);
// 17 is UDP, formerly known as PROTO_UDP
$sock=socket_create(AF_INET,SOCK_DGRAM,17);
$retval=socket_connect($sock,$ip,$radiusport);
//if (!preg_match("/@/",$username))
//$username.=$suffix;
if ($debug)
echo "
radius-port: $radiusport
radius-host:
$radiushost
username: $username
suffix: $suffix<hr>\n";
$RA=pack("CCCCCCCCCCCCCCCC",
// auth code
1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255);
$encryptedpassword=Encrypt($password,$sharedsecret,$RA);
$length= 4+ // header
16+ // auth code
6+ // service type
2+strlen($username)+ // username
2+strlen($encryptedpassword)+ // userpassword
6+ // nasIP
6; // nasPort
$thisidentifier=rand()%256;
// v v v v v v v v
$data=pack("CCCCa*CCCCCCCCa*CCa*CCCCCCCCCCCC",
1,$thisidentifier,$length/256,$length%256, // header
$RA, // authcode
6,6,0,0,0,1, // service type
1,2+strlen($username),$username, // username
2,2+strlen($encryptedpassword),$encryptedpassword, // userpassword
4,6,$nasIP[0],$nasIP[1],$nasIP[2],$nasIP[3], // nasIP
5,3,0,0,0,0 // nasPort
);
echo "
1,$thisidentifier,$length/256,$length%256, // header
$RA, // authcode
6,6,0,0,0,1, // service type
1,2+strlen($username),$username, // username
2,2+strlen($encryptedpassword),$encryptedpassword, // userpassword
4,6,$nasIP[0],$nasIP[1],$nasIP[2],$nasIP[3], // nasIP
5,3,0,0,0,0 // nasPort
";
socket_write($sock,$data,$length);
if ($debug)
echo "
writing $length bytes<hr>\n";
// Wait at most five seconds for the answer. Thanks to
// Michael Long <mlong@infoave.net> for his remark about this.
//
//$set=socket_fd_alloc();
//socket_fd_zero($set);
//socket_fd_set($set,$sock);
//socket_select($set,null,null,5);
//if (!socket_fd_isset($set,$sock)) {
//echo "No answer from radius server, aborting\n";
//exit(0);
}
//socket_fd_free($set);
//$readdata=socket_read($sock,1);
//socket_close($sock);
return ord($readdata);
// 2 -> Access-Accept
// 3 -> Access-Reject
// See RFC2138 for this.
//}
function Encrypt($password,$key,$RA) {
global $debug;
$keyRA=$key.$RA;
if ($debug)
echo "
key: $key
password: $password<hr>\n";
$md5checksum=md5($keyRA);
$output="";
for ($i=0;$i<=15;$i++) {
if (2*$i>strlen($md5checksum)) $m=0; else
$m=hexdec(substr($md5checksum,2*$i,2));
if ($i>strlen($keyRA)) $k=0; else
$k=ord(substr($keyRA,$i,1));
if ($i>strlen($password)) $p=0; else
$p=ord(substr($password,$i,1));
$c=$m^$p;
$output.=chr($c);
}
return $output;
}
?>
Попробовав с ним, как ни странно, появилось продвижение. php стал отсылать пакеты радиусу.
но токо неправильные пакеты.
в логах радиуса такое:
Error: WARNING: Malformed RADIUS packet from host 127.0.0.1: Invalid attribute 0
Из документации радиуса Invalid attribute 0 значит неправильный атрибуит (неправильно сформированый пакет)
вот собственно вопрос: как довести этот скрипт до ума? может есть готовое решение(не замечал в инете)?
ps
система и все компаненты работают корректно пока не производит авторизацию на этотм скрипте.
Если чтойто не верно, скорее поправляйте.