I would like to know if there is any method that can be used to generate vouchers redeemable in the Pfsense captive portal. Basically I have a firewall which feeds internet to a wifi router for guests. I would like to have some form of interface for a worker to be able to create vouchers and give them to customers without having to log in to the wifi. I found two leads online, https://sourceforge.net/projects/vouchergen/ and https://github.com/jpardobl/pfsense_vouchers_rest but they no longer work. Any advice? Thanks in advance.
I just finished writing a simple php page to do that. It works with a mysql database, which has only two tables, one for vouchers and another for IP addresses which I want to grant access to this page.
Once the user chooses a voucher type (minutes) and hit "Generate" then it picks any valid voucher in the local database and marks it as used.
Here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vouchers DSA</title>
</head>
<body>
<?php
function gera_form(){
?>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
<?php
echo '<h2 align="center">Gerador de vouchers para WiFi</center></h2>';
echo '<p align="center">Selecione a duração desejada e clique em "Gerar Voucher"</center></p>';
echo '<br><br>';
echo '<div align="center">';
echo '<form method="POST">';
echo '<select name="state">';
echo '<option value="--">Duração</option>';
echo '<option value="30">1/2 hora</option>';
echo '<option value="60">1 hora</option>';
echo '<option value="120">2 horas</option>';
echo '<option value="1440">1 dia</option>';
echo '<option value="43200">1 mês</option>';
echo '</select>';
echo '<br><br><input type="submit" value="Gerar Voucher">';
echo '</form> </center>';
echo '</div>';
}
$ip=get_client_ip();
$hostname="localhost";
$username="root";
$password="771477";
$db = "banco_voucher";
$dbh = new PDO("mysql:host=$hostname;dbname=$db", $username, $password);
function get_client_ip() {
$ipaddress = '';
if (getenv('HTTP_CLIENT_IP'))
$ipaddress = getenv('HTTP_CLIENT_IP');
else if(getenv('HTTP_X_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_X_FORWARDED_FOR');
else if(getenv('HTTP_X_FORWARDED'))
$ipaddress = getenv('HTTP_X_FORWARDED');
else if(getenv('HTTP_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_FORWARDED_FOR');
else if(getenv('HTTP_FORWARDED'))
$ipaddress = getenv('HTTP_FORWARDED');
else if(getenv('REMOTE_ADDR'))
$ipaddress = getenv('REMOTE_ADDR');
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
function get_voucher($valor, $ip, $dbh){
$hostname="localhost";
$username="root";
$password="771477";
$db = "banco_voucher";
$dbh = new PDO("mysql:host=$hostname;dbname=$db", $username, $password);
foreach($dbh->query("update vouchers
set solicitado_por =
(select id_usuario from usuarios where ip_maquina = '$ip'),
solicitado_em = now(),
validade = 0
where validade != 0 and minutos = '$valor'
limit 1;" ) as $row);
}
function get_time($minutos){
$dur = "";
if ($minutos == 30) {
$dur = "1/2 hora";
} else if ($minutos == 60) {
$dur = "1 hora";
} else if ($minutos == 120) {
$dur = "2 horas";
} else if ($minutos == 1440) {
$dur = "1 dia";
} else if ($minutos == 43200) {
$dur = "1 mes";
} else {
$dur = "desconhecida";
}
return $dur;
}
function gera_tabela($ip){
$hostname="localhost";
$username="root";
$password="771477";
$db = "banco_voucher";
$dbh = new PDO("mysql:host=$hostname;dbname=$db", $username, $password);
$historico = array("<table>
<tr>
<th>Departamento</th>
<th>Voucher</th>
<th>Duracao</th>
<th>Data</th>
</tr>",);
$teste = array ("a");
try {
$select = $dbh->query("select b.departamento,
a.cod_voucher, a.minutos,
date_format(a.solicitado_em, '%d/%c/%Y - %H:%i:%s') as stamp
from vouchers as a
right join usuarios as b on (solicitado_por = id_usuario)
where ip_maquina = '$ip' and cod_voucher is not null
order by stamp desc limit 10;");
} catch (Exception $exc) {
echo $exc->getTraceAsString();
}
$result = $select->fetchAll();
echo "<br><br>";
echo $historico[0];
$i = 0;
foreach($result as $row){
$dur = get_time($row['minutos']);
array_push($historico, "<tr><td>".$row['departamento']."</td>"
. "<td>".$row['cod_voucher']."</td>"
. "<td>".$dur."</td>"
. "<td>".$row['stamp']."</td>"
. "</tr>");
$i++;
echo $historico[$i];
}
echo "</table>";
}
foreach($dbh->query("select-count(ip_maquina) as ip from usuarios where ip_maquina = '$ip';") as $row){
if($row['ip'] == 0){
echo "<h1>Acesso negado</h1>";
echo "<p>Sua estação de trabalho não tem as permissões de acesso necessárias."
. "<br>Contate a equipe de TI para mais informações.</p><hr>";
echo "<address>Gestão de vouchers - Divisão Sul Americana da IASD</address>";
}
else if($row['ip'] != 0){
gera_form();
get_voucher($_POST['state'], $ip);
gera_tabela($ip);
if(isset($_POST['state'])){
header("Location:SandBox.php");
unset($_POST['state']);
if($_POST['state']=="--"){
echo "Escolha um tempo apropriado para a validade do voucher.";
}
}
}
}
?>
</body>
</html>
As it is my first php page, it might be a disaster in an experienced php programmer's eyes, however it is quite functional and does right what you seem to need.
Just copy the code above into a file named SandBox.php and place in your Apache /www/html folder.
The tables in mysql can be created using these codes:
For vouchers:
CREATE TABLE `vouchers` (
`id_voucher` int(11) NOT NULL AUTO_INCREMENT,
`cod_voucher` varchar(10) DEFAULT NULL,
`validade` bit(1) DEFAULT NULL,
`solicitado_em` varchar(20) DEFAULT NULL,
`solicitado_por` varchar(15) DEFAULT NULL,
`minutos` int(11) DEFAULT NULL,
PRIMARY KEY (`id_voucher`)
) ENGINE=InnoDB AUTO_INCREMENT=131073 DEFAULT CHARSET=utf8;
You must do a manual update in the column 'validade' to set the value '1' [meaning valid] for all vouchers. After picked by the page, it will be updated into '0' [meaning used].
update vouchers set validade = 1;
For IP addresses which will be allowed to access the page:
CREATE TABLE `usuarios` (
`id_usuario` int(11) NOT NULL AUTO_INCREMENT,
`ip_maquina` varchar(15) DEFAULT NULL,
`departamento` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id_usuario`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
You must do manual inserts in this table, parsing the IP address of the management machine and it's name/location/label/whatever you want to use as a human readable ID.
insert into usuarios(ip_maquina, departamento) values ('10.91.198.12', 'Cyber Cafe');
PS.: The field names are in portuguese.
To load the .csv file from PfSense into the local database:
LOAD DATA LOCAL INFILE '/home/infra/Downloads/vouchers.csv'
INTO TABLE vouchers
LINES TERMINATED BY '\n' (cod_voucher);
Hope it may help you.