diff --git a/src/EAPPacket.php b/src/EAPPacket.php index f966a9a..639b326 100644 --- a/src/EAPPacket.php +++ b/src/EAPPacket.php @@ -26,13 +26,14 @@ class EAPPacket public $id; public $type; public $data; - + /** * Helper function to generate an EAP Identity packet * - * @param string $identity The identity (username) to send in the packet - * @param int $id The packet ID (random if omitted) + * @param string $identity The identity (username) to send in the packet + * @param int $id The packet ID (random if omitted) * @return string An EAP identity packet + * @throws \Exception */ public static function identity($identity, $id = null) { @@ -42,15 +43,16 @@ public static function identity($identity, $id = null) $packet->type = self::TYPE_IDENTITY; $packet->data = $identity; - return $packet->__toString(); + return (string) $packet; } - + /** * Helper function to generate an EAP Legacy NAK packet * - * @param string $desiredAuth The desired auth method - * @param int $id The packet ID, given by server at predecessing proposal + * @param string $desiredAuth The desired auth method + * @param int $id The packet ID, given by server at predecessing proposal * @return string An EAP Legacy NAK packet + * @throws \Exception */ public static function legacyNak($desiredAuth, $id) { @@ -60,32 +62,31 @@ public static function legacyNak($desiredAuth, $id) $packet->type = self::TYPE_NAK; $packet->data = chr($desiredAuth); - return $packet->__toString(); + return (string) $packet; } - + /** * Helper function to generate an EAP Success packet * - * @param string $desiredAuth The identity (username) to send in the packet - * @param int $id The packet ID, given by server at predecessing proposal + * @param int $id The packet ID, given by server at predecessing proposal * @return string An EAP Legacy NAK packet + * @throws \Exception */ public static function eapSuccess($id) { $eapSuccess = new MsChapV2Packet(); $eapSuccess->opcode = MsChapV2Packet::OPCODE_SUCCESS; - - $packet = self::mschapv2($eapSuccess, $id); - - return $packet; + + return self::mschapv2($eapSuccess, $id); } - + /** * Helper function for sending an MS-CHAP-V2 packet encapsulated in an EAP packet * - * @param \Dapphp\Radius\MsChapV2Packet $chapPacket The MSCHAP v2 packet to send - * @param int $id The CHAP packet identifier (random if omitted) + * @param \Dapphp\Radius\MsChapV2Packet $chapPacket The MSCHAP v2 packet to send + * @param int $id The CHAP packet identifier (random if omitted) * @return string An EAP packet with embedded MS-CHAP-V2 packet in the data field + * @throws \Exception */ public static function mschapv2(\Dapphp\Radius\MsChapV2Packet $chapPacket, $id = null) { @@ -93,16 +94,16 @@ public static function mschapv2(\Dapphp\Radius\MsChapV2Packet $chapPacket, $id = $packet->setId($id); $packet->code = self::CODE_RESPONSE; $packet->type = self::TYPE_EAP_MS_AUTH; - $packet->data = $chapPacket->__toString(); + $packet->data = (string) $chapPacket; - return $packet->__toString(); + return (string) $packet; } /** * Convert a raw EAP packet into a structure * * @param string $packet The EAP packet - * @return \Dapphp\Radius\EAPPacket The parsed packet structure + * @return \Dapphp\Radius\EAPPacket|bool The parsed packet structure */ public static function fromString($packet) { @@ -118,23 +119,25 @@ public static function fromString($packet) return false; } - $p->type = ord(substr($packet, 4, 1)); + $p->type = ord($packet[4]); $p->data = substr($packet, 5); return $p; } - + /** * Set the ID of the EAP packet - * @param int $id The EAP packet ID + * + * @param int $id The EAP packet ID * @return \Dapphp\Radius\EAPPacket Fluent interface + * @throws \Exception */ public function setId($id = null) { if (is_null($id)) { - $this->id = mt_rand(0, 255); + $this->id = random_int(0, 255); } else { - $this->id = (int)$id; + $this->id = (int) $id; } return $this; diff --git a/src/MsChapV2Packet.php b/src/MsChapV2Packet.php index 5216443..98456f0 100644 --- a/src/MsChapV2Packet.php +++ b/src/MsChapV2Packet.php @@ -71,7 +71,7 @@ public static function fromString($packet) public function __toString() { $packet = pack('C', $this->opcode) . - chr($this->msChapId) . + chr($this->msChapId ?? 0) . "\x00\x00"; // temp length switch($this->opcode) { diff --git a/src/Radius.php b/src/Radius.php index 9a0342a..b5db81c 100644 --- a/src/Radius.php +++ b/src/Radius.php @@ -272,9 +272,9 @@ public function getLastError() { if (0 < $this->errorCode) { return $this->errorMessage.' ('.$this->errorCode.')'; - } else { - return ''; } + + return ''; } /** @@ -440,7 +440,7 @@ public function getEncryptedPassword($password, $secret, $requestAuthenticator) $previous = ''; for ($j = 0; $j <= 15; ++$j) { - $value1 = ord(substr($paddedPassword, ($i * 16) + $j, 1)); + $value1 = ord($paddedPassword[($i * 16) + $j]); $value2 = hexdec(substr($temp, 2 * $j, 2)); $xor_result = $value1 ^ $value2; $previous .= chr($xor_result); @@ -524,18 +524,19 @@ public function getChapPassword($password, $chapId, $requestAuthenticator) { return md5(pack('C', $chapId) . $password . $requestAuthenticator, true); } - + /** * Set the MS-CHAP password in the RADIUS packet (for authentication using MS-CHAP passwords) * - * @param string $password The plaintext password - * @param string $challenge The CHAP challenge + * @param string $password The plaintext password + * @param string $challenge The CHAP challenge * @return self + * @throws \Exception */ public function setMsChapPassword($password, $challenge = null) { $chap = new \Crypt_CHAP_MSv1(); - $chap->chapid = mt_rand(1, 255); + $chap->chapid = random_int(1, 255); $chap->password = $password; if (is_null($challenge)) { $chap->generateChallenge(); @@ -597,7 +598,7 @@ public function getNasIPAddress() */ public function setNasPort($port = 0) { - $this->nasPort = intval($port); + $this->nasPort = (int) $port; $this->setAttribute(5, $this->nasPort); return $this; @@ -621,8 +622,8 @@ public function getNasPort() */ public function setTimeout($timeout = 5) { - if (intval($timeout) > 0) { - $this->timeout = intval($timeout); + if ((int) $timeout > 0) { + $this->timeout = (int) $timeout; } return $this; @@ -646,8 +647,8 @@ public function getTimeout() */ public function setAuthenticationPort($port) { - if ((intval($port) > 0) && (intval($port) < 65536)) { - $this->authenticationPort = intval($port); + if (((int) $port > 0) && ((int) $port < 65536)) { + $this->authenticationPort = (int) $port; } return $this; @@ -671,9 +672,9 @@ public function getAuthenticationPort() */ public function setAccountingPort($port) { - if ((intval($port) > 0) && (intval($port) < 65536)) + if (((int) $port > 0) && ((int) $port < 65536)) { - $this->accountingPort = intval($port); + $this->accountingPort = (int) $port; } return $this; @@ -753,7 +754,7 @@ public function getAttribute($type) if (is_array($this->attributesReceived)) { foreach($this->attributesReceived as $attr) { - if (intval($type) == $attr[0]) { + if ((int) $type == $attr[0]) { $value = $attr[1]; break; } @@ -772,11 +773,11 @@ public function getAttribute($type) */ public function getRadiusPacketInfo($info_index) { - if (isset($this->radiusPackets[intval($info_index)])) { - return $this->radiusPackets[intval($info_index)]; - } else { - return ''; + if (isset($this->radiusPackets[(int) $info_index])) { + return $this->radiusPackets[(int) $info_index]; } + + return ''; } /** @@ -788,11 +789,11 @@ public function getRadiusPacketInfo($info_index) */ public function getAttributesInfo($info_index) { - if (isset($this->attributesInfo[intval($info_index)])) { - return $this->attributesInfo[intval($info_index)]; - } else { - return array('', ''); + if (isset($this->attributesInfo[(int) $info_index])) { + return $this->attributesInfo[(int) $info_index]; } + + return array('', ''); } /** @@ -839,9 +840,9 @@ public function setAttribute($type, $value) case 'I': // Integer, 32 bit unsigned value, most significant octet first. $temp = chr($type) . chr(6) . - chr(intval(($value / (256 * 256 * 256))) % 256) . - chr(intval(($value / (256 * 256))) % 256) . - chr(intval(($value / (256))) % 256) . + chr((int) ($value / (256 * 256 * 256)) % 256) . + chr((int) ($value / (256 * 256)) % 256) . + chr((int) ($value / (256)) % 256) . chr($value % 256); break; case 'D': @@ -884,19 +885,19 @@ public function getAttributesToSend($type = null) if (is_array($this->attributesToSend)) { if ($type == null) { return $this->attributesToSend; - } else { - foreach($this->attributesToSend as $i => $attr) { - if (is_array($attr)) { - $tmp = $attr[0]; - } else { - $tmp = $attr; - } - if ($type == ord(substr($tmp, 0, 1))) { - return $this->decodeAttribute(substr($tmp, 2), $type); - } + } + + foreach($this->attributesToSend as $i => $attr) { + if (is_array($attr)) { + $tmp = $attr[0]; + } else { + $tmp = $attr; + } + if ($type == ord(substr($tmp, 0, 1))) { + return $this->decodeAttribute(substr($tmp, 2), $type); } - return null; } + return null; } return array(); @@ -980,15 +981,16 @@ public function decodeVendorSpecificContent($rawValue) { $result = array(); $offset = 0; - $vendorId = (ord(substr($rawValue, 0, 1)) * 256 * 256 * 256) + - (ord(substr($rawValue, 1, 1)) * 256 * 256) + - (ord(substr($rawValue, 2, 1)) * 256) + - ord(substr($rawValue, 3, 1)); + $vendorId = (ord($rawValue[0]) * 256 * 256 * 256) + + (ord($rawValue[1]) * 256 * 256) + + (ord($rawValue[2]) * 256) + + ord($rawValue[3]); $offset += 4; - while ($offset < strlen($rawValue)) { - $vendorType = (ord(substr($rawValue, 0 + $offset, 1))); - $vendorLength = (ord(substr($rawValue, 1 + $offset, 1))); + $len = strlen($rawValue); + while ($offset < $len) { + $vendorType = ord($rawValue[$offset]); + $vendorLength = ord($rawValue[1 + $offset]); $attributeSpecific = substr($rawValue, 2 + $offset, $vendorLength); $result[] = array($vendorId, $vendorType, $attributeSpecific); $offset += $vendorLength; @@ -1026,7 +1028,7 @@ public function accessRequest($username = '', $password = '', $timeout = 0, $sta $this->setAttribute(6, 1); // 1=Login } - if (intval($timeout) > 0) { + if ((int) $timeout > 0) { $this->setTimeout($timeout); } @@ -1110,15 +1112,17 @@ public function accessRequestList($serverList, $username = '', $password = '', $ $this->setServer($server); $result = $this->accessRequest($username, $password, $timeout, $state); - + if ($result === true) { break; // success - } elseif ($this->getErrorCode() === self::TYPE_ACCESS_REJECT) { + } + + if ($this->getErrorCode() === self::TYPE_ACCESS_REJECT) { break; // access rejected - } else { - /* timeout or other possible transient error; try next host */ - $this->attributesToSend = $attributes; // reset base attributes } + + /* timeout or other possible transient error; try next host */ + $this->attributesToSend = $attributes; // reset base attributes } return $result; @@ -1204,10 +1208,8 @@ public function accessRequestEapMsChapV2($username, $password) $this->setUsername($username) ->setAttribute(79, $eapPacket) ->setIncludeMessageAuthenticator(); - - $resp = $this->accessRequest('', '', 0, $state); - - if (!$resp) { + + if (!$this->accessRequest('', '', 0, $state)) { return false; } @@ -1372,17 +1374,19 @@ public function changePasswordEapMsChapV2($username, $password, $newPassword) $this->errorMessage = 'Password must be expired to be changed'; return false; } - + if ($this->radiusPacketReceived == self::TYPE_ACCESS_REJECT) { $this->errorCode = 3; $this->errorMessage = 'Access rejected, invalid account'; return false; - } elseif ($this->radiusPacketReceived != self::TYPE_ACCESS_CHALLENGE) { + } + + if ($this->radiusPacketReceived != self::TYPE_ACCESS_CHALLENGE) { $this->errorCode = 102; $this->errorMessage = 'Access-Request did not get Access-Challenge response'; return false; } - + $state = $this->getReceivedAttribute(24); $eap = $this->getReceivedAttribute(79); @@ -1528,15 +1532,17 @@ public function accessRequestEapMsChapV2List($serverList, $username, $password) $this->setServer($server); $result = $this->accessRequestEapMsChapV2($username, $password); - + if ($result === true) { break; // success - } elseif ($this->getErrorCode() === self::TYPE_ACCESS_REJECT) { + } + + if ($this->getErrorCode() === self::TYPE_ACCESS_REJECT) { break; // access rejected - } else { - /* timeout or other possible transient error; try next host */ - $this->attributesToSend = $attributes; // reset base attributes } + + /* timeout or other possible transient error; try next host */ + $this->attributesToSend = $attributes; // reset base attributes } return $result; @@ -1712,18 +1718,18 @@ private function parseRadiusResponsePacket($packet) $this->errorMessage = 'Response authenticator in received packet did not match expected value'; return false; } - - while (strlen($attrContent) > 2) { - $attrType = intval(ord(substr($attrContent, 0, 1))); - $attrLength = intval(ord(substr($attrContent, 1, 1))); + + $len = strlen($attrContent); + while ($len > 2) { + $attrType = (int) ord($attrContent[0]); + $attrLength = (int) ord($attrContent[1]); $attrValueRaw = substr($attrContent, 2, $attrLength - 2); $attrContent = substr($attrContent, $attrLength); $attrValue = $this->decodeAttribute($attrValueRaw, $attrType); $attr = $this->getAttributesInfo($attrType); if (26 == $attrType) { - $vendorArr = $this->decodeVendorSpecificContent($attrValue); - foreach($vendorArr as $vendor) { + foreach($this->decodeVendorSpecificContent($attrValue) as $vendor) { $this->debugInfo( sprintf( 'Attribute %d (%s), length %d, format %s, Vendor-Id: %d, Vendor-type: %s, Attribute-specific: %s', @@ -1797,7 +1803,7 @@ public function generateRadiusPacket() if ($hasAuthenticator && !is_null($offset)) { $messageAuthenticator = hash_hmac('md5', $packetData, $this->secret, true); // calculate packet hmac, replace hex 0's with actual hash - for ($i = 0; $i < strlen($messageAuthenticator); ++$i) { + for ($i = 0, $iMax = strlen($messageAuthenticator); $i < $iMax; ++$i) { $packetData[20 + $offset + $i] = $messageAuthenticator[$i]; } } @@ -1830,13 +1836,16 @@ public function getNextIdentifier() $this->identifierToSend = (($this->identifierToSend + 1) % 256); return $this->identifierToSend; } - + + /** + * @throws \Exception + */ private function generateRequestAuthenticator() { $this->requestAuthenticator = ''; for ($c = 0; $c <= 15; ++$c) { - $this->requestAuthenticator .= chr(rand(1, 255)); + $this->requestAuthenticator .= chr(random_int(1, 255)); } return $this; @@ -1905,7 +1914,7 @@ protected function debugInfo($message) $msg .= $message; $msg .= "
\n"; - if (php_sapi_name() == 'cli') { + if (php_sapi_name() === 'cli') { $msg = strip_tags($msg); } diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 17376a6..c959972 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -122,8 +122,8 @@ public function testCryptCHAPMSv1Indirect() $chapChallenge = $client->getAttributesToSend(26); $vendor = unpack('NID', substr($chapChallenge, 0, 4)); - $type = ord(substr($chapChallenge, 4, 1)); - $length = ord(substr($chapChallenge, 5, 1)); + $type = ord($chapChallenge[4]); + $length = ord($chapChallenge[5]); $data = substr($chapChallenge, 6, $length); $this->assertEquals(VendorId::MICROSOFT, $vendor['ID']); @@ -247,40 +247,40 @@ public function testMsChapV1Packet() $this->assertEquals($expected, $packet); } - + public function testEapPacketBasic() { $p = new MsChapV2Packet(); $p->opcode = MsChapV2Packet::OPCODE_SUCCESS; - $s = $p->__toString(); - + $s = (string) $p; + $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($expected, bin2hex((string) $p)); + + $parsed = EAPPacket::fromString((string) $p); + $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()); - + + $p3 = EAPPacket::fromString((string) $p2); + $this->assertEquals(EAPPacket::CODE_RESPONSE, $p3->code); $this->assertEquals(128, $p3->id); $this->assertEquals(2, $p3->type);