mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-23 17:34:17 +03:00
fixed tunnel to allow sending to broker connection stats on termination
This commit is contained in:
parent
c796f5aaac
commit
50660d92e5
@ -11,7 +11,7 @@
|
|||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
# and/or other materials provided with the distribution.
|
# and/or other materials provided with the distribution.
|
||||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
|
||||||
# may be used to endorse or promote products derived from this software
|
# may be used to endorse or promote products derived from this software
|
||||||
# without specific prior written permission.
|
# without specific prior written permission.
|
||||||
#
|
#
|
||||||
@ -31,9 +31,9 @@
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import typing
|
import typing
|
||||||
from uds.models.user_service import UserService
|
|
||||||
|
|
||||||
from uds import models
|
from uds import models
|
||||||
|
from uds.core import managers
|
||||||
from uds.REST import Handler
|
from uds.REST import Handler
|
||||||
from uds.REST import AccessDenied
|
from uds.REST import AccessDenied
|
||||||
from uds.core.auths.auth import isTrustedSource
|
from uds.core.auths.auth import isTrustedSource
|
||||||
@ -42,6 +42,7 @@ from uds.core.util.stats import events
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
MAX_SESSION_LENGTH = 60*60*24*7
|
||||||
|
|
||||||
# Enclosed methods under /tunnel path
|
# Enclosed methods under /tunnel path
|
||||||
class Tunnel(Handler):
|
class Tunnel(Handler):
|
||||||
@ -56,12 +57,12 @@ class Tunnel(Handler):
|
|||||||
Processes get requests, currently none
|
Processes get requests, currently none
|
||||||
"""
|
"""
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'Tunnel parameters for GET: %s from %s', self._args, self._request.ip
|
'Tunnel parameters for GET: %s (%s) from %s', self._args, self._params, self._request.ip
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
not isTrustedSource(self._request.ip)
|
not isTrustedSource(self._request.ip)
|
||||||
or len(self._args) > 2
|
or len(self._args) != 2
|
||||||
or len(self._args[0]) != 48
|
or len(self._args[0]) != 48
|
||||||
):
|
):
|
||||||
# Invalid requests
|
# Invalid requests
|
||||||
@ -69,16 +70,22 @@ class Tunnel(Handler):
|
|||||||
|
|
||||||
# Try to get ticket from DB
|
# Try to get ticket from DB
|
||||||
try:
|
try:
|
||||||
user, userService, host, port, _ = models.TicketStore.get_for_tunnel(
|
user, userService, host, port, extra = models.TicketStore.get_for_tunnel(
|
||||||
self._args[0]
|
self._args[0]
|
||||||
)
|
)
|
||||||
start = len(self._args) == 2 # Start requests include source IP request
|
|
||||||
|
|
||||||
if net.ipToLong(self._args[1][:32]) == 0:
|
|
||||||
raise Exception('Invalid from IP')
|
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
if start:
|
if self._args[1][:4] == 'stop':
|
||||||
|
sent, recv = self._params['sent'], self._params['recv']
|
||||||
|
# Ensures extra exists...
|
||||||
|
extra = extra or {}
|
||||||
|
now = models.getSqlDatetimeAsUnix()
|
||||||
|
totalTime = now - extra.get('b', now-1)
|
||||||
|
msg = f'User {user.name} stopped tunnel {extra.get("t", "")[:8]}... to {host}:{port}: s:{sent}/r:{recv}/t:{totalTime}.'
|
||||||
|
log.doLog(user.manager, log.INFO, msg)
|
||||||
|
log.doLog(userService, log.INFO, msg)
|
||||||
|
else:
|
||||||
|
if net.ipToLong(self._args[1][:32]) == 0:
|
||||||
|
raise Exception('Invalid from IP')
|
||||||
events.addEvent(
|
events.addEvent(
|
||||||
userService.deployed_service,
|
userService.deployed_service,
|
||||||
events.ET_TUNNEL_ACCESS,
|
events.ET_TUNNEL_ACCESS,
|
||||||
@ -87,10 +94,22 @@ class Tunnel(Handler):
|
|||||||
dstip=host,
|
dstip=host,
|
||||||
uniqueid=userService.unique_id,
|
uniqueid=userService.unique_id,
|
||||||
)
|
)
|
||||||
msg = f'User {user.name} started tunnel to {host}:{port} from {self._args[1]}.'
|
msg = f'User {user.name} started tunnel {self._args[0][:8]}... to {host}:{port} from {self._args[1]}.'
|
||||||
log.doLog(user.manager, log.INFO, msg)
|
log.doLog(user.manager, log.INFO, msg)
|
||||||
log.doLog(userService, log.INFO, msg)
|
log.doLog(userService, log.INFO, msg)
|
||||||
data = {'host': host, 'port': port}
|
# Generate new, notify only, ticket
|
||||||
|
rstr = managers.cryptoManager().randomString(length=8)
|
||||||
|
notifyTicket = models.TicketStore.create_for_tunnel(
|
||||||
|
userService=userService,
|
||||||
|
port=port,
|
||||||
|
host=host,
|
||||||
|
extra={'t': self._args[0], 'b': models.getSqlDatetimeAsUnix()},
|
||||||
|
validity=MAX_SESSION_LENGTH)
|
||||||
|
data = {
|
||||||
|
'host': host,
|
||||||
|
'port': port,
|
||||||
|
'notify': notifyTicket
|
||||||
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -57,4 +57,4 @@ COMMAND_LENGTH = 4
|
|||||||
COMMAND_OPEN = b'OPEN'
|
COMMAND_OPEN = b'OPEN'
|
||||||
COMMAND_TEST = b'TEST'
|
COMMAND_TEST = b'TEST'
|
||||||
COMMAND_STAT = b'STAT' # full stats
|
COMMAND_STAT = b'STAT' # full stats
|
||||||
COMMAND_INFO = b'INFO' # Basic stats
|
COMMAND_INFO = b'INFO' # Basic stats, currently same as FULL
|
@ -52,6 +52,19 @@ class Proxy:
|
|||||||
self.cfg = cfg
|
self.cfg = cfg
|
||||||
self.ns = ns
|
self.ns = ns
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _getUdsUrl(cfg: config.ConfigurationType, ticket: bytes, msg: str) -> typing.MutableMapping[str, typing.Any]:
|
||||||
|
try:
|
||||||
|
url = cfg.uds_server + '/' + ticket.decode() + '/' + msg
|
||||||
|
r = requests.get(url, headers={'content-type': 'application/json'})
|
||||||
|
if not r.ok:
|
||||||
|
raise Exception(r.content)
|
||||||
|
|
||||||
|
return r.json()
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f'TICKET COMMS ERROR: {e!s}')
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getFromUds(
|
def getFromUds(
|
||||||
cfg: config.ConfigurationType, ticket: bytes,
|
cfg: config.ConfigurationType, ticket: bytes,
|
||||||
@ -70,16 +83,12 @@ class Proxy:
|
|||||||
continue # Correctus
|
continue # Correctus
|
||||||
raise Exception(f'TICKET INVALID (char {i} at pos {n})')
|
raise Exception(f'TICKET INVALID (char {i} at pos {n})')
|
||||||
|
|
||||||
try:
|
return Proxy._getUdsUrl(cfg, ticket, address[0])
|
||||||
url = cfg.uds_server + '/' + ticket.decode() + '/' + address[0]
|
|
||||||
r = requests.get(url, headers={'content-type': 'application/json'})
|
|
||||||
if not r.ok:
|
|
||||||
raise Exception(r.content)
|
|
||||||
|
|
||||||
return r.json()
|
|
||||||
except Exception as e:
|
|
||||||
raise Exception(f'TICKET COMMS ERROR: {e!s}')
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def notifyEndToUds(cfg: config.ConfigurationType, ticket: bytes, counter: stats.Stats) -> None:
|
||||||
|
msg = f'stop?sent={counter.sent}&recv={counter.recv}'
|
||||||
|
Proxy._getUdsUrl(cfg, ticket, msg) # Ignore results
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def doProxy(source, destination, counter: stats.StatsSingleCounter) -> None:
|
async def doProxy(source, destination, counter: stats.StatsSingleCounter) -> None:
|
||||||
@ -194,6 +203,7 @@ class Proxy:
|
|||||||
logger.debug('PROXIES READY')
|
logger.debug('PROXIES READY')
|
||||||
|
|
||||||
logger.debug('Proxies finalized: %s', grp.exceptions)
|
logger.debug('Proxies finalized: %s', grp.exceptions)
|
||||||
|
await curio.run_in_thread(Proxy.notifyEndToUds, self.cfg, result['notify'].encode(), counter)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if consts.DEBUG:
|
if consts.DEBUG:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# pidfile = /tmp/udstunnel.pid
|
# pidfile = /tmp/udstunnel.pid
|
||||||
|
|
||||||
# Log level, valid are DEBUG, INFO, WARN, ERROR. Defaults to ERROR
|
# Log level, valid are DEBUG, INFO, WARN, ERROR. Defaults to ERROR
|
||||||
loglevel = INFO
|
loglevel = DEBUG
|
||||||
|
|
||||||
# Log file, Defaults to stdout
|
# Log file, Defaults to stdout
|
||||||
# logfile = /tmp/tunnel.log
|
# logfile = /tmp/tunnel.log
|
||||||
|
Loading…
Reference in New Issue
Block a user