<?php
/*
userlist.php - ViaVoip
Copyright (C) 2015 Attilio Pavone <tilly@utillyty.eu>
This file is part of ViaVoip.
ViaVoip is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ViaVoip is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ViaVoip. If not, see <http://www.gnu.org/licenses/>.
*/
// tilly 25/04/2016
include("global.php");
vvv_response_begin();
vvv_db_open();
// ----------------------
// delete expired records
// ----------------------
$sql = "DELETE FROM vvv_userlist WHERE mtime<'".vvv_db_time(time() - VVV_EXPIRE_TIME)."'";
vvv_db_exec($sql);
// NB: cannot use 'REMOTE_ADDR' as id: ip shared by all computers behind the same LAN!
$ip = $_SERVER['REMOTE_ADDR'];
$cmd = intval($_REQUEST['cmd']);
switch ($cmd) {
// ----------------------
// insert/update user
// ----------------------
case 1:
$endpoint = stripslashes($_REQUEST['endpoint']);
$alt_endpoint = stripslashes($_REQUEST['alt_endpoint']);
$nickname = stripslashes($_REQUEST['nickname']);
validate_endpoint($endpoint);
if ($alt_endpoint)
validate_endpoint($alt_endpoint);
// ----------------------
// select data
// ----------------------
// select call
$sql = "SELECT `call`, `alt_call` FROM vvv_userlist WHERE endpoint='" . vvv_db_escape($endpoint) . "'";
$result = vvv_db_query($sql);
if($rec = vvv_db_fetch($result)) {
vvv_response_write($rec['call']);
vvv_response_write($rec['alt_call']);
} else {
vvv_response_write("");
vvv_response_write("");
}
// select caller nickname if present
if ($rec) {
$sql = "SELECT nickname FROM vvv_userlist WHERE endpoint='" . vvv_db_escape($rec['call']) . "'";
$result = vvv_db_query($sql);
if($rec = vvv_db_fetch($result))
vvv_response_write($rec['nickname']);
else
vvv_response_write("");
} else {
vvv_response_write("");
}
// ----------------------
// update data
// ----------------------
// delete user
$sql = "DELETE FROM vvv_userlist WHERE endpoint='" . vvv_db_escape($endpoint) . "'";
$level = vvv_db_exec($sql) == 0 ? VVV_ERR_NOTICE : VVV_ERR_INFO; // if not present (vvv_db_exec($sql) == 0) will be inserted
// (re)insert user
$sql = "INSERT INTO vvv_userlist (ip, endpoint, alt_endpoint, nickname, mtime)"
. " VALUES ('$ip', '" . vvv_db_escape($endpoint) . "'"
. ", '" . vvv_db_escape($alt_endpoint) . "'"
. ", '" . vvv_db_escape($nickname) . "'"
. ", '" . vvv_db_time(time()) . "'"
. ")";
vvv_db_exec($sql);
$message = "user visible";
break;
// ----------------------
// place call
// ----------------------
case 2:
$call = stripslashes($_REQUEST['call']);
$alt_call = stripslashes($_REQUEST['alt_call']);
$endpoint = stripslashes($_REQUEST['endpoint']);
validate_endpoint($call);
if ($alt_call)
validate_endpoint($alt_call);
$sql = "UPDATE vvv_userlist"
. " SET `call`='" . vvv_db_escape($call) . "'"
. " , `alt_call`='" . vvv_db_escape($alt_call) . "'"
. " WHERE endpoint='" . vvv_db_escape($endpoint) . "'";
if (vvv_db_exec($sql) > 0) {
$level = VVV_ERR_NOTICE;
$message = "calling user";
} else {
$level = VVV_ERR_WARNING;
$message = "user not found";
}
break;
// ----------------------
// delete user
// ----------------------
case -1:
$endpoint = stripslashes($_REQUEST['endpoint']);
validate_endpoint($endpoint);
$sql = "DELETE FROM vvv_userlist WHERE endpoint='" . vvv_db_escape($endpoint) . "'";
vvv_db_exec($sql);
vvv_response_write(""); // empty call, alt_call and nickname (client uses same func as 1)
vvv_response_write("");
vvv_response_write("");
$level = VVV_ERR_NOTICE;
//$level = vvv_db_exec($sql) > 0 ? VVV_ERR_NOTICE : VVV_ERR_INFO; better highlight this info anyway
$message = "user hidden";
break;
// ----------------------
// get users list
// ----------------------
default:
$sql = "SELECT endpoint, alt_endpoint, nickname FROM vvv_userlist";
$result = vvv_db_query($sql);
$userlist = "";
while($rec = vvv_db_fetch($result)){
$userlist .= $rec['endpoint']."\t".$rec['alt_endpoint']."\t".$rec['nickname']."\r";
// NB: - \n is VVV protocol line separator
// - NOT using ';' to avoid conflict with string values (i.e. nickname)
// - of course this implementation is ok for a short list
// (I don't ever expect having many thousands of users...)
}
vvv_response_write($userlist);
$level = VVV_ERR_INFO;
$message = "public list ok";
break;
}
if (($cmd != 1) || ($level > VVV_ERR_INFO)) // 1.4 do not log status confirmations
vvv_log($level, $message);
vvv_response_end($level, $message);
// =============================================================================
function validate_endpoint($endpoint)
{
if (strpos($endpoint, "::") <= 0)
vvv_response_end(VVV_ERR_CRITICAL, "invalid endpoint string");
$a = explode("::", $endpoint);
if (count($a) != 2)
vvv_response_end(VVV_ERR_CRITICAL, "invalid endpoint string");
$proto = $a[0];
if ($proto != "tcp" && $proto != "udp")
vvv_response_end(VVV_ERR_CRITICAL, "invalid endpoint protocol");
$endpoint = $a[1];
if (strpos($endpoint, ":") <= 0)
vvv_response_end(VVV_ERR_CRITICAL, "invalid endpoint string");
$a = explode(":", $endpoint);
if (count($a) != 2)
vvv_response_end(VVV_ERR_CRITICAL, "invalid endpoint string");
$ip = $a[0];
if (!filter_var($ip, FILTER_VALIDATE_IP))
vvv_response_end(VVV_ERR_CRITICAL, "invalid endpoint ip");
$ports = $a[1];
if ($proto == "tcp") {
$ports = intval($ports);
if ($ports < 1 || $ports > 65535)
vvv_response_end(VVV_ERR_CRITICAL, "invalid endpoint port");
} else {
if (strpos($ports, ",") <= 0)
vvv_response_end(VVV_ERR_CRITICAL, "invalid UDP ports");
$ports = explode(",", $ports);
if (count($ports) != 2)
vvv_response_end(VVV_ERR_CRITICAL, "invalid UDP ports");
if (intval($ports[0]) < 1 || intval($ports[0]) > 65535)
vvv_response_end(VVV_ERR_CRITICAL, "invalid UDP connection port");
if (intval($ports[1]) < 1 || intval($ports[1]) > 65535)
vvv_response_end(VVV_ERR_CRITICAL, "invalid UDP audio port");
}
return TRUE;
}