From 14eaa0beabb2eed42e48de21cdb497a96a169eda Mon Sep 17 00:00:00 2001 From: Zsombor Date: Mon, 9 Jan 2023 10:36:26 +0200 Subject: [PATCH 1/4] wip: try source address --- webssh/handler.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/webssh/handler.py b/webssh/handler.py index 6cfc822..43db8bd 100644 --- a/webssh/handler.py +++ b/webssh/handler.py @@ -377,6 +377,12 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): raise InvalidValueError('Invalid port: {}'.format(value)) return port + def get_source_address(self): + value = self.get_value('source_address') + if not is_valid_ip_address(value): + raise InvalidValueError('Invalid ip address: {}'.format(value)) + return value + def lookup_hostname(self, hostname, port): key = hostname if port == 22 else '[{}]:{}'.format(hostname, port) @@ -395,6 +401,7 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): privatekey, filename = self.get_privatekey() passphrase = self.get_argument('passphrase', u'') totp = self.get_argument('totp', u'') + source_address = self.get_argument('source_address', u'') if isinstance(self.policy, paramiko.RejectPolicy): self.lookup_hostname(hostname, port) @@ -405,7 +412,7 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): pkey = None self.ssh_client.totp = totp - args = (hostname, port, username, password, pkey) + args = (hostname, port, username, password, pkey, source_address) logging.debug(args) return args @@ -451,8 +458,17 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): dst_addr = args[:2] logging.info('Connecting to {}:{}'.format(*dst_addr)) + # WIP ZM + sock = socket.socket() + sock.settimeout(5) # otherwise it will hang if host is unreachable + sock.bind((args[5], 0)) + print(args) + sock.connect((args[0], args[1])) + + + try: - ssh.connect(*args, timeout=options.timeout) + ssh.connect(*args, timeout=options.timeout, sock=sock) except socket.error: raise ValueError('Unable to connect to {}:{}'.format(*dst_addr)) except paramiko.BadAuthenticationType: @@ -600,4 +616,4 @@ class WsockHandler(MixinHandler, tornado.websocket.WebSocketHandler): worker = self.worker_ref() if self.worker_ref else None if worker: - worker.close(reason=self.close_reason) + worker.close(reason=self.close_reason) \ No newline at end of file From fc7e19d21e0c30372b4169c514c2a95b34a5b087 Mon Sep 17 00:00:00 2001 From: Zsombor Date: Mon, 9 Jan 2023 16:47:29 +0200 Subject: [PATCH 2/4] feature: source address gui field and error handling --- webssh/handler.py | 34 ++++++++++++++++++++++------------ webssh/templates/index.html | 2 ++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/webssh/handler.py b/webssh/handler.py index 43db8bd..5aaeef8 100644 --- a/webssh/handler.py +++ b/webssh/handler.py @@ -380,7 +380,7 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): def get_source_address(self): value = self.get_value('source_address') if not is_valid_ip_address(value): - raise InvalidValueError('Invalid ip address: {}'.format(value)) + raise InvalidValueError('Invalid source ip address: {}'.format(value)) return value def lookup_hostname(self, hostname, port): @@ -401,7 +401,7 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): privatekey, filename = self.get_privatekey() passphrase = self.get_argument('passphrase', u'') totp = self.get_argument('totp', u'') - source_address = self.get_argument('source_address', u'') + source_address = self.get_source_address() if isinstance(self.policy, paramiko.RejectPolicy): self.lookup_hostname(hostname, port) @@ -411,8 +411,19 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): else: pkey = None + if source_address: + logging.info("Binding socket for source ip {}".format(source_address)) + sock = socket.socket() + sock.settimeout(options.timeout) # Set a timeout on blocking socket operations + try: + sock.bind((source_address, 0)) + except OSError: + raise InvalidValueError('Unable to bind source address {} socket'.format(source_address)) + else: + sock = None + self.ssh_client.totp = totp - args = (hostname, port, username, password, pkey, source_address) + args = (hostname, port, username, password, pkey, sock) logging.debug(args) return args @@ -458,17 +469,16 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): dst_addr = args[:2] logging.info('Connecting to {}:{}'.format(*dst_addr)) - # WIP ZM - sock = socket.socket() - sock.settimeout(5) # otherwise it will hang if host is unreachable - sock.bind((args[5], 0)) - print(args) - sock.connect((args[0], args[1])) - - + sock = args[5] + if sock: + logging.info('Connecting source address socket') + try: + sock.connect(dst_addr) + except socket.error: + raise ValueError('Unable to connect source address socket to {}:{}'.format(*dst_addr)) try: - ssh.connect(*args, timeout=options.timeout, sock=sock) + ssh.connect(*args, timeout=options.timeout) except socket.error: raise ValueError('Unable to connect to {}:{}'.format(*dst_addr)) except paramiko.BadAuthenticationType: diff --git a/webssh/templates/index.html b/webssh/templates/index.html index 3268c38..4b27e32 100644 --- a/webssh/templates/index.html +++ b/webssh/templates/index.html @@ -77,6 +77,8 @@
+ +
From ab3f4b68de0613635fbfe1af1d20297ad63d5ea8 Mon Sep 17 00:00:00 2001 From: Zsombor Date: Tue, 10 Jan 2023 12:33:22 +0200 Subject: [PATCH 3/4] fix: optional source address field --- webssh/handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webssh/handler.py b/webssh/handler.py index 5aaeef8..6617000 100644 --- a/webssh/handler.py +++ b/webssh/handler.py @@ -378,8 +378,8 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): return port def get_source_address(self): - value = self.get_value('source_address') - if not is_valid_ip_address(value): + value = self.get_argument('source_address', u'') + if value and not is_valid_ip_address(value): raise InvalidValueError('Invalid source ip address: {}'.format(value)) return value From 0a3e0325684646ebedf060b80a9081b27304b7d3 Mon Sep 17 00:00:00 2001 From: mzsombor <38425339+mzsombor@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:56:09 +0200 Subject: [PATCH 4/4] Update handler.py fix: socket moved to ssh_connect --- webssh/handler.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/webssh/handler.py b/webssh/handler.py index 6617000..86708d4 100644 --- a/webssh/handler.py +++ b/webssh/handler.py @@ -401,7 +401,7 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): privatekey, filename = self.get_privatekey() passphrase = self.get_argument('passphrase', u'') totp = self.get_argument('totp', u'') - source_address = self.get_source_address() + source_address = self.get_argument('source_address', u'') if isinstance(self.policy, paramiko.RejectPolicy): self.lookup_hostname(hostname, port) @@ -411,19 +411,8 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): else: pkey = None - if source_address: - logging.info("Binding socket for source ip {}".format(source_address)) - sock = socket.socket() - sock.settimeout(options.timeout) # Set a timeout on blocking socket operations - try: - sock.bind((source_address, 0)) - except OSError: - raise InvalidValueError('Unable to bind source address {} socket'.format(source_address)) - else: - sock = None - self.ssh_client.totp = totp - args = (hostname, port, username, password, pkey, sock) + args = (hostname, port, username, password, pkey, source_address) logging.debug(args) return args @@ -469,16 +458,23 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): dst_addr = args[:2] logging.info('Connecting to {}:{}'.format(*dst_addr)) - sock = args[5] - if sock: + sock = None + source_address = args[5] + if source_address: logging.info('Connecting source address socket') + sock = socket.socket() + sock.settimeout(options.timeout) # Set a timeout on blocking socket operations + try: + sock.bind((source_address, 0)) + except OSError: + raise InvalidValueError('Unable to bind source address {} socket'.format(source_address)) try: sock.connect(dst_addr) except socket.error: raise ValueError('Unable to connect source address socket to {}:{}'.format(*dst_addr)) try: - ssh.connect(*args, timeout=options.timeout) + ssh.connect(*args, sock=sock, timeout=options.timeout) except socket.error: raise ValueError('Unable to connect to {}:{}'.format(*dst_addr)) except paramiko.BadAuthenticationType: @@ -626,4 +622,4 @@ class WsockHandler(MixinHandler, tornado.websocket.WebSocketHandler): worker = self.worker_ref() if self.worker_ref else None if worker: - worker.close(reason=self.close_reason) \ No newline at end of file + worker.close(reason=self.close_reason)