1 |
5b237745
|
Scott Ullrich
|
<?php
|
2 |
|
|
//
|
3 |
|
|
// $Id$
|
4 |
|
|
//
|
5 |
|
|
// radius authentication v1.0 by Edwin Groothuis (edwin@mavetju.org)
|
6 |
|
|
//
|
7 |
|
|
// If you didn't get this file via http://www.mavetju.org, please
|
8 |
|
|
// check for the availability of newer versions.
|
9 |
|
|
//
|
10 |
|
|
// See LICENSE for distribution issues. If this file isn't in
|
11 |
|
|
// the distribution, please inform me about it.
|
12 |
|
|
//
|
13 |
|
|
// If you want to use this script, fill in the configuration in
|
14 |
|
|
// radius_authentication.conf and call the function
|
15 |
|
|
// RADIUS_AUTHENTICATION() with the username and password
|
16 |
|
|
// provided by the user. If it returns a 2, the authentication
|
17 |
|
|
// was successfull!
|
18 |
|
|
|
19 |
|
|
// If you want to use this, make sure that you have raw sockets
|
20 |
|
|
// enabled during compile-time: "./configure --enable-sockets".
|
21 |
|
|
|
22 |
|
|
// This version has been modified by Dinesh Nair <dinesh@alphaque.com>
|
23 |
|
|
// for use in the m0n0wall distribution http://m0n0.ch/wall/
|
24 |
|
|
//
|
25 |
|
|
// Changes include moving from raw sockets to fsockopen
|
26 |
|
|
// and the removal of dependency on external conf file
|
27 |
|
|
// An existing bug which resulted in a malformed RADIUS packet
|
28 |
|
|
// was also fixed and patches submitted to Edwin. This bug would
|
29 |
|
|
// have caused authentication to fail on every access.
|
30 |
|
|
|
31 |
480d71dc
|
Scott Ullrich
|
function RADIUS_AUTHENTICATION($username,$password,$radiusip,$radiusport,$radiuskey) {
|
32 |
5b237745
|
Scott Ullrich
|
$sharedsecret=$radiuskey ;
|
33 |
33f0abb1
|
Scott Ullrich
|
# $debug = 1 ;
|
34 |
5b237745
|
Scott Ullrich
|
|
35 |
|
|
exec("/bin/hostname", $nasHostname) ;
|
36 |
|
|
if(!$nasHostname[0])
|
37 |
269239d7
|
Scott Ullrich
|
$nasHostname[0] = "m0n0wall" ;
|
38 |
5b237745
|
Scott Ullrich
|
|
39 |
|
|
$fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
|
40 |
269239d7
|
Scott Ullrich
|
if(!$fd)
|
41 |
5b237745
|
Scott Ullrich
|
return 1 ; /* error return */
|
42 |
269239d7
|
Scott Ullrich
|
|
43 |
5b237745
|
Scott Ullrich
|
/* set 5 second timeout on socket i/o */
|
44 |
|
|
stream_set_timeout($fd, 5) ;
|
45 |
|
|
|
46 |
|
|
if ($debug)
|
47 |
|
|
echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
|
48 |
|
|
|
49 |
|
|
$RA=pack("CCCCCCCCCCCCCCCC", // auth code
|
50 |
|
|
1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
|
51 |
|
|
1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
|
52 |
|
|
1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
|
53 |
|
|
1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255);
|
54 |
|
|
|
55 |
|
|
$encryptedpassword=Encrypt($password,$sharedsecret,$RA);
|
56 |
|
|
|
57 |
|
|
$length=4+ // header
|
58 |
|
|
16+ // auth code
|
59 |
|
|
6+ // service type
|
60 |
|
|
2+strlen($username)+ // username
|
61 |
|
|
2+strlen($encryptedpassword)+ // userpassword
|
62 |
|
|
2+strlen($nasHostname[0])+ // nasIdentifier
|
63 |
|
|
6+ // nasPort
|
64 |
|
|
6; // nasPortType
|
65 |
|
|
|
66 |
|
|
$thisidentifier=rand()%256;
|
67 |
|
|
// v v v v v v v v v
|
68 |
|
|
// Line # 1 2 3 4 5 6 7 8 E
|
69 |
|
|
$data=pack("CCCCa*CCCCCCCCa*CCa*CCa*CCCCCCCCCCCC",
|
70 |
|
|
1,$thisidentifier,$length/256,$length%256, // header
|
71 |
|
|
$RA, // authcode
|
72 |
|
|
6,6,0,0,0,1, // service type
|
73 |
|
|
1,2+strlen($username),$username, // username
|
74 |
|
|
2,2+strlen($encryptedpassword),$encryptedpassword, // userpassword
|
75 |
|
|
32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
|
76 |
|
|
5,6,0,0,0,0, // nasPort
|
77 |
480d71dc
|
Scott Ullrich
|
61,6,0,0,0,15 // nasPortType = Ethernet
|
78 |
5b237745
|
Scott Ullrich
|
);
|
79 |
|
|
|
80 |
|
|
if($debug) {
|
81 |
|
|
echo "username is $username with len " . strlen($username) ."\n" ;
|
82 |
|
|
echo "encryptedpassword is $encryptedpassword with len " . strlen($encryptedpassword) ."\n" ;
|
83 |
|
|
echo "nasHostname is {$nasHostname[0]} with len " . strlen($nasHostname[0]) ."\n" ;
|
84 |
269239d7
|
Scott Ullrich
|
}
|
85 |
5b237745
|
Scott Ullrich
|
|
86 |
|
|
$ret = fwrite($fd,$data) ;
|
87 |
269239d7
|
Scott Ullrich
|
if( !$ret || ($ret != $length) )
|
88 |
5b237745
|
Scott Ullrich
|
return 1; /* error return */
|
89 |
|
|
|
90 |
|
|
if ($debug)
|
91 |
|
|
echo "<br>writing $length bytes<hr>\n";
|
92 |
|
|
|
93 |
33f0abb1
|
Scott Ullrich
|
$readdata = fgets($fd,2) ; /* read 1 byte */
|
94 |
|
|
$status = socket_get_status($fd) ;
|
95 |
|
|
fclose($fd) ;
|
96 |
|
|
|
97 |
|
|
if($status['timed_out'])
|
98 |
|
|
$retvalue = 1 ;
|
99 |
|
|
else
|
100 |
|
|
$retvalue = ord($readdata) ;
|
101 |
|
|
|
102 |
|
|
return $retvalue ;
|
103 |
5b237745
|
Scott Ullrich
|
// 2 -> Access-Accept
|
104 |
|
|
// 3 -> Access-Reject
|
105 |
|
|
// See RFC2865 for this.
|
106 |
|
|
}
|
107 |
|
|
|
108 |
|
|
function Encrypt($password,$key,$RA) {
|
109 |
|
|
global $debug;
|
110 |
|
|
|
111 |
|
|
$keyRA=$key.$RA;
|
112 |
|
|
|
113 |
|
|
if ($debug)
|
114 |
|
|
echo "<br>key: $key<br>password: $password<hr>\n";
|
115 |
|
|
|
116 |
|
|
$md5checksum=md5($keyRA);
|
117 |
|
|
$output="";
|
118 |
|
|
|
119 |
|
|
for ($i=0;$i<=15;$i++) {
|
120 |
|
|
if (2*$i>strlen($md5checksum)) $m=0; else $m=hexdec(substr($md5checksum,2*$i,2));
|
121 |
|
|
if ($i>strlen($keyRA)) $k=0; else $k=ord(substr($keyRA,$i,1));
|
122 |
|
|
if ($i>strlen($password)) $p=0; else $p=ord(substr($password,$i,1));
|
123 |
|
|
$c=$m^$p;
|
124 |
|
|
$output.=chr($c);
|
125 |
|
|
}
|
126 |
|
|
return $output;
|
127 |
|
|
}
|
128 |
33f0abb1
|
Scott Ullrich
|
?>
|