setAttribute(80, $test); $attr = $client->getAttributesToSend(80); $this->assertEquals($test, $attr); $client->removeAttribute(80); $attr = $client->getAttributesToSend(80); $this->assertEquals(null, $attr); // integer value test $nasPort = 32768; $client->setAttribute(5, $nasPort); $attr = $client->getAttributesToSend(5); $this->assertEquals($nasPort, $attr); $client->removeAttribute(5); $attr = $client->getAttributesToSend(5); $this->assertEquals(null, $attr); } public function testGetAttributes() { $client = new Radius(); $username = 'LinusX2@arpa.net'; $nasIp = '192.168.88.1'; $nasPort = 64000; $expected = ''; // manually constructed hex string $expected .= chr(1); // username $expected .= chr(2 + strlen($username)); // length $expected .= $username; $expected .= chr(4); // nas ip $expected .= chr(6); $expected .= pack('N', ip2long($nasIp)); $expected .= chr(5); // nas port $expected .= chr(6); $expected .= pack('N', $nasPort); $client->setUsername($username) ->setNasIPAddress($nasIp) ->setNasPort($nasPort); $actual = implode('', $client->getAttributesToSend()); $this->assertEquals($expected, $actual); $this->assertEquals($username, $client->getAttributesToSend(1)); $this->assertEquals($nasIp, $client->getAttributesToSend(4)); $this->assertEquals($nasPort, $client->getAttributesToSend(5)); } public function testEncryptedPassword() { $pass = 'arctangent'; $secret = 'xyzzy5461'; $requestAuthenticator = "\x0f\x40\x3f\x94\x73\x97\x80\x57\xbd\x83\xd5\xcb\x98\xf4\x22\x7a"; $client = new Radius(); $expected = "\x0d\xbe\x70\x8d\x93\xd4\x13\xce\x31\x96\xe4\x3f\x78\x2a\x0a\xee"; $encrypted = $client->getEncryptedPassword($pass, $secret, $requestAuthenticator); $this->assertEquals($expected, $encrypted); } public function testEncryptedPassword2() { $pass = 'm1cr0$ofT_W1nDoWz*'; $secret = '%iM8WD3(9bSh4jXNyOH%4W6RE1s4bfQ#0h*n^lOz'; $requestAuthenticator = "\x7d\x22\x56\x6c\x9d\x2d\x50\x26\x88\xc5\xb3\xf9\x33\x77\x14\x55"; $client = new Radius(); $expected = "\x44\xe0\xac\xdc\xed\x56\x39\x67\xb1\x41\x90\xef\x3e\x10\xca\x2c\xb5\xb0\x5f\xf6\x6c\x31\x87\xf0\x2a\x92\xcb\x65\xeb\x97\x31\x1f"; $encrypted = $client->getEncryptedPassword($pass, $secret, $requestAuthenticator); $this->assertEquals($expected, $encrypted); } public function testCryptCHAPMSv1() { $pass = "Don't forget to bring a passphrase!"; $chap = new \Crypt_CHAP_MSv1(); $chap->password = $pass; $chap->chapid = 42; $chap->challenge = "\x6c\x7e\x0d\xba\xe3\x81\xea\x51"; $response = $chap->ntChallengeResponse(); $this->assertEquals('5f169b7d8176516f8092bce99008e097febfed2f043ec04e', bin2hex($response)); } public function testCryptCHAPMSv1Indirect() { // Ensure Pear_CHAP_MSv1 can be loaded by Radius and that setting the attributes works $pass = "This is ms-chap ~~++"; $chal = "\x02\x04\x08\x10\x20\x40\x80\x00"; // 8 byte 'random' challenge $client = new Radius(); $client->setMsChapPassword($pass, $chal); $chapChallenge = $client->getAttributesToSend(26); $vendor = unpack('NID', substr($chapChallenge, 0, 4)); $type = ord(substr($chapChallenge, 4, 1)); $length = ord(substr($chapChallenge, 5, 1)); $data = substr($chapChallenge, 6, $length); $this->assertEquals(VendorId::MICROSOFT, $vendor['ID']); $this->assertEquals(11, $type); // chap challenge $this->assertEquals($chal, $data); } public function testCryptCHAPMSv2() { $pass = 'Passwords < Passphrases < $whatsNext?'; $chap = new \Crypt_CHAP_MSv2(); $chap->username = 'nemo'; $chap->password = $pass; $chap->chapid = 37; $chap->authChallenge = "\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10"; $chap->peerChallenge = "\x93\xa8\x14\xc3\x90\x4e\x67\xcc\xb1\xd2\x72\x23\xd5\xf3\x90\xae"; $response = $chap->challengeResponse(); $this->assertEquals('a3d12ce2f52d13fe04421205a2ce17b0e559ea8a9e594c1c', bin2hex($response)); } public function testAuthenticationPacket() { $user = 'nemo'; $pass = 'arctangent'; $secret = 'xyzzy5461'; $nas = '192.168.1.16'; $nasPort = 3; $client = new Radius(); $client->setRequestAuthenticator("\x0f\x40\x3f\x94\x73\x97\x80\x57\xbd\x83\xd5\xcb\x98\xf4\x22\x7a"); $client->setPacketType(Radius::TYPE_ACCESS_REQUEST) ->setSecret($secret) ->setUsername($user) ->setPassword($pass) ->setNasIPAddress($nas) ->setNasPort($nasPort); $packet = $client->generateRadiusPacket(); $pwEnc = "\x0d\xbe\x70\x8d\x93\xd4\x13\xce\x31\x96\xe4\x3f\x78\x2a\x0a\xee"; $expected = "\x01\x00\x00\x38\x0f\x40\x3f\x94\x73\x97\x80\x57\xbd\x83" . "\xd5\xcb\x98\xf4\x22\x7a\x01\x06\x6e\x65\x6d\x6f\x02\x12" . $pwEnc . "\x04\x06\xc0\xa8\x01\x10\x05\x06\x00\x00\x00\x03"; $this->assertEquals($expected, $packet); } public function testFramedAuthPacket() { $user = 'flopsy'; $pass = 'arctangent'; $reqAuth = "\x2a\xee\x86\xf0\x8d\x0d\x55\x96\x9c\xa5\x97\x8e\x0d\x33\x67\xa2"; $nas = '192.168.1.16'; $nasPort = 20; $expected = "\x01\x01\x00\x47\x2a\xee\x86\xf0\x8d\x0d\x55\x96\x9c\xa5" ."\x97\x8e\x0d\x33\x67\xa2\x01\x08\x66\x6c\x6f\x70\x73\x79" ."\x03\x13\x16\xe9\x75\x57\xc3\x16\x18\x58\x95\xf2\x93\xff" ."\x63\x44\x07\x72\x75\x04\x06\xc0\xa8\x01\x10\x05\x06\x00" ."\x00\x00\x14\x06\x06\x00\x00\x00\x02\x07\x06\x00\x00\x00\x01"; $client = new Radius(); $client->getNextIdentifier(); // increment to 1 for test $client->setChapId(22); $client->setRequestAuthenticator($reqAuth) ->setPacketType(Radius::TYPE_ACCESS_REQUEST) ->setUsername($user) ->setChapPassword($pass) ->setNasIPAddress($nas) ->setNasPort($nasPort) ->setAttribute(6, 2) // service type (6) = framed (2) ->setAttribute(7, 1); // framed protocol (7) = ppp (1) $packet = $client->generateRadiusPacket(); $this->assertEquals($expected, $packet); } public function testHmacMd5() { $str = hex2bin('01870082093e4ad125399f8ac4ba6b00ab69a04001066e656d6f04067f0000010506000000145012000000000000000000000000000000001a10000001370b0a740c7921e45e91391a3a00000137013400010000000000000000000000000000000000000000000000004521bd46aebfd2ab3ec21dd6e6bbfa2e4ff325eab720fe37'); $hash = hash_hmac('md5', $str, 'xyzzy5461', true); $expected = '48a3704ac91e8191497a1f3f213eb338'; $actual = bin2hex($hash); $this->assertEquals($expected, $actual); } public function testMsChapV1Packet() { $reqId = 135; $user = 'nemo'; $pass = 'arctangent123$'; $secret = 'xyzzy5461'; $reqAuth = "\x09\x3e\x4a\xd1\x25\x39\x9f\x8a\xc4\xba\x6b\x00\xab\x69\xa0\x40"; $nas = '127.0.0.1'; $nasPort = 20; $challenge = "\x74\x0c\x79\x21\xe4\x5e\x91\x39"; $client = new Radius(); $client->setPacketType(Radius::TYPE_ACCESS_REQUEST) ->setNextIdentifier($reqId) ->setRequestAuthenticator($reqAuth) ->setSecret($secret) ->setUsername($user) ->setNasIPAddress($nas) ->setNasPort($nasPort) ->setAttribute(80, str_repeat("\x00", 16)) ->setMsChapPassword($pass, $challenge); $packet = $client->generateRadiusPacket(); $packet = bin2hex($packet); $expected = "01870082093e4ad125399f8ac4ba6b00ab69a04001066e656d6f04067f000001050600000014501248a3704ac91e8191497a1f3f213eb3381a10000001370b0a740c7921e45e91391a3a00000137013400010000000000000000000000000000000000000000000000004521bd46aebfd2ab3ec21dd6e6bbfa2e4ff325eab720fe37"; $this->assertEquals($expected, $packet); } public function testEapPacketBasic() { $p = new MsChapV2Packet(); $p->opcode = MsChapV2Packet::OPCODE_SUCCESS; $s = $p->__toString(); $this->assertEquals("\x03", $s, "MsChapV2Packet success returns 0x03 without error"); $p = new EAPPacket(); $p->code = EAPPacket::CODE_REQUEST; $p->id = 111; $p->type = EAPPacket::TYPE_IDENTITY; $p->data = 'here is some data'; $expected = "016f0016016865726520697320736f6d652064617461"; $this->assertEquals($expected, bin2hex($p->__toString())); $parsed = EAPPacket::fromString($p->__toString()); $this->assertEquals(EAPPacket::CODE_REQUEST, $parsed->code); $this->assertEquals(111, $parsed->id); $this->assertEquals(EAPPacket::TYPE_IDENTITY, $parsed->type); $this->assertEquals($p->data, $parsed->data); $p2 = new EAPPacket(); $p2->code = EAPPacket::CODE_RESPONSE; $p2->id = 128; $p2->type = EAPPacket::TYPE_NOTIFICATION; $p2->data = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x99\x98\x97\x96\x95\x94\x93\x92\x91\x90"; $p3 = EAPPacket::fromString($p2->__toString()); $this->assertEquals(EAPPacket::CODE_RESPONSE, $p3->code); $this->assertEquals(128, $p3->id); $this->assertEquals(2, $p3->type); $this->assertEquals("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x99\x98\x97\x96\x95\x94\x93\x92\x91\x90", $p3->data); } public function testEapMsChapV2() { $server = getenv('RADIUS_SERVER_ADDR'); $user = getenv('RADIUS_USER'); $pass = getenv('RADIUS_PASS'); $secret = getenv('RADIUS_SECRET'); if (!$server) { $this->markTestSkipped('RADIUS_SERVER_ADDR environment variable not set'); } elseif (!$user) { $this->markTestSkipped('RADIUS_USER environment variable not set'); } elseif (!$pass) { $this->markTestSkipped('RADIUS_PASS environment variable not set'); } elseif (!$secret) { $this->markTestSkipped('RADIUS_SECRET environment variable not set'); } $client = new Radius(); $client->setServer($server) ->setSecret($secret); $success = $client->accessRequestEapMsChapV2($user, $pass); $this->assertTrue($success); } }