hello everyone, I introduce myself as a new user.
How can I read a hotspot user’s password with php?
example: typing the user name in a html form the php script returns me the password.
thanks
Using the API client from my signature:
<?php
use PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b6.phar';
$util = new RouterOS\Util($client = new RouterOS\Client('192.168.88.1', 'admin', 'password'));
echo $util->setMenu('/ip hotspot user')->get('user1', 'password');
This will output the password for “user1”. Note that the RouterOS user needs to have both “read” and “sensitive” permissions to read passwords - just “read” permissions are not sufficient… Obviously also “api” permissions in order to be able to use the API protocol.
Great ![]()
I have another question:
if I enter a non-existent user I have a fatal error
Fatal error: Uncaught exception ‘PEAR2\Net\RouterOS\RouterErrorException’ with message ‘Error getting property’ in phar:
I solved this by inserting
By catching the exception and showing the error there:
try {
echo $util->setMenu('/ip hotspot user')->get('user1', 'password');
} catch (RouterOS\RouterErrorException $e) {
echo '<script>alert("Your USER ID not found or is wrong."); window.location.href = "https://www.google.com";</script>';
} catch (Exception $e) {
echo '<script>alert("Something went wrong while trying to get your password. Please try again later."); window.location.href = "https://www.google.com";</script>';
}
That last part is a catch all for any other error, such as a sudden disconnect for example. With it, you can safely remove the “error_reporting(0);”, since no exception will remain uncaught in that case.
You can fine tune the error handling by having multiple catch clauses for each known possible error and inspecting the $e variable for further details.
Perfect!!! ![]()
I tried the code and it works fine, but on some users I have the following error:
user 12345
exception ‘PEAR2\Net\RouterOS\RouterErrorException’ with message ‘Unable to resolve number from ID cache (no such item maybe)’ in phar://C:/webserver/PEAR2_Net_RouterOS-1.0.0b6.phar/PEAR2_Net_RouterOS-1.0.0b6/src/PEAR2/Net/RouterOS/Util.php:549 Stack trace: #0 C:\webserver\readpassword.php(10): PEAR2\Net\RouterOS\Util->get(‘12345’, ‘password’) #1 {main}
![]()
This is an example of Util being overly helpful… my bad…
Because the terminal can accept numbers, and yet the API can’t, under the hood, when you attempt to get an item with a number, Util indexes all IDs into a numeric array, and then gets the ID out of it. That’s the ID cache. It normally works great… except apparently when the name is actually numeric too.
I’ll modify Util to not use the ID cache when you use a numeric string, and instead only use it when you give an integer, but in the meantime, what you can do is to use a query, e.g.:
$util->setMenu('/ip hotspot user')->get(RouterOS\Query::where('name', '12345'), 'password');
Under the hood, that’s slower than giving the name directly, because there’s two API calls instead of just one - one call to get the ID of 12345, and a second call to get the password for that ID.
If you want to avoid that overhead, you can not use Util::get(), and use Client instead, but in that case, error handling is done differently - errors coming from the router do not throw an exception. Only errors coming from the client (e.g. a sudden disconnect) result in exceptions. You’d need to check if there are errors in the reply, and act accordingly. e.g.
try {
$responses = $client->sendSync($util->setMenu('/ip hotspot user')->newRequest('get', array('number' => '12345', 'value-name' => 'password'));
$errors = $responses->getAllOfType(RouterOS\Response::TYPE_ERROR);
if (empty($errors)) {
echo $responses->end()->getProperty('ret');
} else {
echo '<script>alert("Your USER ID not found or is wrong."); window.location.href = "https://www.google.com";</script>';
}
} catch (Exception $e) {
echo '<script>alert("Something went wrong while trying to get your password. Please try again later."); window.location.href = "https://www.google.com";</script>';
}