aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Touhey <thomas@touhey.fr>2022-09-10 16:31:29 +0200
committerThomas Touhey <thomas@touhey.fr>2022-09-10 16:31:29 +0200
commit7aa4d6da423b4ac8cde845dc4a555e88eb48d26e (patch)
treefbdae63fff880746363b02e7972272df481e6941
parent1f676e721e81713d9f1cf7cb00482890d68c9ea2 (diff)
Fixed some bad behaviours from the command-line interface
-rw-r--r--pyfingerd/binds.py30
-rwxr-xr-xpyfingerd/cli.py42
-rwxr-xr-xpyfingerd/core.py13
-rwxr-xr-xpyfingerd/errors.py4
4 files changed, 72 insertions, 17 deletions
diff --git a/pyfingerd/binds.py b/pyfingerd/binds.py
index 069be3e..0de3bc6 100644
--- a/pyfingerd/binds.py
+++ b/pyfingerd/binds.py
@@ -156,6 +156,10 @@ class FingerBindsDecoder:
else:
raise _InvalidBindError(addr, 'Garbage found after the host')
+ # Manage localhost by default.
+ if not host:
+ host = 'localhost'
+
# Decode the host part and get the addresses.
addrs = ()
if is_ipv6:
@@ -168,11 +172,17 @@ class FingerBindsDecoder:
try:
ip = host.split('.')
if len(ip) < 2 or len(ip) > 4:
- raise AssertionError('2 <= len(ip) <= 4')
+ raise _InvalidBindError(
+ addr,
+ f'Expected a valid IP address, got {host!r}.',
+ )
ip = list(map(int, ip))
if not all(lambda x: 0 <= x < 256, ip):
- raise AssertionError('non-8-bit component')
+ raise _InvalidBindError(
+ addr,
+ f'Expected a valid IP address, got {host!r}.',
+ )
if len(ip) == 2:
ip = [ip[0], 0, 0, ip[1]]
@@ -181,11 +191,17 @@ class FingerBindsDecoder:
addrs += (FingerTCPv4Bind(ip, port),)
except Exception:
- entries = _socket.getaddrinfo(
- host, port,
- proto=_socket.IPPROTO_TCP,
- type=_socket.SOCK_STREAM,
- )
+ try:
+ entries = _socket.getaddrinfo(
+ host, port,
+ proto=_socket.IPPROTO_TCP,
+ type=_socket.SOCK_STREAM,
+ )
+ except _socket.gaierror:
+ raise _InvalidBindError(
+ addr,
+ f'Invalid IP address and unresolved host: {host!r}',
+ )
for ent in entries:
if (
diff --git a/pyfingerd/cli.py b/pyfingerd/cli.py
index 659892c..56b001d 100755
--- a/pyfingerd/cli.py
+++ b/pyfingerd/cli.py
@@ -21,6 +21,7 @@ from .core import (
FingerInterface as _FingerInterface,
FingerServer as _FingerServer,
)
+from .errors import BindError as _BindError
from .fiction import (
FingerScenario as _FingerScenario,
FingerScenarioInterface as _FingerScenarioInterface,
@@ -53,13 +54,13 @@ __all__ = ['cli']
)
@_click.option(
'-t', '--type', 'type_',
- default='native', envvar=('FINGER_TYPE',),
+ default=None, envvar=('FINGER_TYPE',),
show_default=True,
help='Interface type for gathering user and session data.',
)
@_click.option(
'-s', '--scenario',
- default='actions.toml',
+ default=None,
envvar=('FINGER_SCENARIO', 'FINGER_ACTIONS'),
help="Path to the scenario, if the selected type is 'scenario'.",
)
@@ -90,11 +91,30 @@ def cli(binds, hostname, type_, scenario, scenario_start, log_level):
)
hostname = hostname.upper()
+
+ if type_ is None:
+ if scenario is not None:
+ type_ = 'scenario'
+ else:
+ type_ = 'native'
+
type_ = type_.casefold()
+ if scenario is not None and type_ not in ('actions', 'scenario'):
+ _logger.warning(
+ "Since the type isn't 'scenario', the provided scenario "
+ + 'path will be ignored.',
+ )
if type_ == 'native':
iface = _FingerNativeInterface()
elif type_ in ('actions', 'scenario'):
+ if scenario is None:
+ _logger.error(
+ 'Scenario interface selected, but the scenario has not '
+ + 'been provided; please do so.',
+ )
+ return 1
+
try:
fic = _FingerScenario.load(scenario)
iface = _FingerScenarioInterface(fic, scenario_start)
@@ -106,13 +126,19 @@ def cli(binds, hostname, type_, scenario, scenario_start, log_level):
_logger.error('Error loading the scenario:')
_logger.error('%s%s.', exc[0].upper(), exc[1:])
return 1
- elif type_ != 'dummy':
- print(
- 'warning: unknown interface type, falling back on dummy',
- file=_stderr,
- )
else:
+ if type_ != 'dummy':
+ _logger.warning(
+ 'Unknown interface type %r, falling back on dummy',
+ type_,
+ )
+
iface = _FingerInterface()
- server = _FingerServer(binds=binds, hostname=hostname, interface=iface)
+ try:
+ server = _FingerServer(binds=binds, hostname=hostname, interface=iface)
+ except _BindError as exc:
+ _logger.error('%s', exc.original_message)
+ return 1
+
server.serve_forever()
diff --git a/pyfingerd/core.py b/pyfingerd/core.py
index 0f40e51..36b8b0e 100755
--- a/pyfingerd/core.py
+++ b/pyfingerd/core.py
@@ -946,7 +946,7 @@ class FingerServer:
else:
users = self.interface.search_users(None, True)
_access_logger.info(
- '%s requested connection users: found %s.',
+ '%s requested connected users: found %s.',
src, (
{0: 'no user', 1: '1 user'}
.get(len(users), f'{len(users)} users')
@@ -975,7 +975,10 @@ class FingerServer:
outp.write(b'An internal exception has occurred.\r\n')
outp.close()
- await outp.wait_closed()
+ try:
+ await outp.wait_closed()
+ except Exception:
+ _logger.exception('Failed closing the connection:')
async def start_server(bind):
"""Start a given server."""
@@ -1005,6 +1008,12 @@ class FingerServer:
+ 'port and process is unprivileged.',
host, port, port,
)
+ elif name == 'EADDRNOTAVAIL':
+ _logger.error(
+ 'Could not bind to [%s]:%d: %s is not '
+ + 'available to bind.',
+ host, port, host,
+ )
else:
raise
else:
diff --git a/pyfingerd/errors.py b/pyfingerd/errors.py
index 2e72b94..796325c 100755
--- a/pyfingerd/errors.py
+++ b/pyfingerd/errors.py
@@ -32,6 +32,7 @@ class BindError(ConfigurationError):
"""Raised when an error has occurred with the provided binds."""
def __init__(self, msg):
+ self.original_message = msg
super().__init__(
f'An error has occurred with the provided binds: {msg}',
)
@@ -53,6 +54,9 @@ class InvalidBindError(BindError):
+ f'was invalid{": " + msg if msg else ""}',
)
+ if msg is not None:
+ self.original_message = msg
+
class MalformedQueryError(Exception):
"""Raised when a malformed query is received."""