1
|
<?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
|
function RADIUS_AUTHENTICATION($username,$password,$radiusip,$radiusport,$radiuskey) {
|
32
|
$sharedsecret=$radiuskey ;
|
33
|
# $debug = 1 ;
|
34
|
|
35
|
exec("/bin/hostname", $nasHostname) ;
|
36
|
if(!$nasHostname[0])
|
37
|
$nasHostname[0] = "m0n0wall" ;
|
38
|
|
39
|
$fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
|
40
|
if(!$fd)
|
41
|
return 1 ; /* error return */
|
42
|
|
43
|
/* 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
|
61,6,0,0,0,15 // nasPortType = Ethernet
|
78
|
);
|
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
|
}
|
85
|
|
86
|
$ret = fwrite($fd,$data) ;
|
87
|
if( !$ret || ($ret != $length) )
|
88
|
return 1; /* error return */
|
89
|
|
90
|
if ($debug)
|
91
|
echo "<br>writing $length bytes<hr>\n";
|
92
|
|
93
|
$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
|
// 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
|
?>
|