Commit 7fc33c00 authored by Scott Kuhl's avatar Scott Kuhl Committed by Brian May

Refactor debug, log and Fatal messages.

This commit rewrites the log() function so that it will append a
newline at the end of the message if none is present. It doesn't make
sense to print a log message without a newline since the next log
message (which will write a prefix) expects to be starting at the
beginning of a line.

Although it isn't strictly necessary, this commit also removes any
newlines at the ends of messages. If I missed any, including the
newline at the end of the message will continue to work as it did
before.

Previously, some calls were missing the newline at the end even though
including it was necessary for subsequent messages to appear
correctly.

This code also cleans up some redundant prefixes. The log() method
will prepend the prefix and the different processes should set their
prefix as soon as they start.

Multiline messages are still supported (although the prefix for the
additional lines was changed to match the length of the prefix used
for the first line).
parent 563f4147
This diff is collapsed.
......@@ -117,9 +117,9 @@ def main():
return return_code
except Fatal as e:
log('fatal: %s\n' % e)
log('fatal: %s' % e)
return 99
except KeyboardInterrupt:
log('\n')
log('Keyboard interrupt: exiting.\n')
log('Keyboard interrupt: exiting.')
return 1
......@@ -51,15 +51,14 @@ def rewrite_etc_hosts(hostmap, port):
def restore_etc_hosts(hostmap, port):
# Only restore if we added hosts to /etc/hosts previously.
if len(hostmap) > 0:
debug2('undoing /etc/hosts changes.\n')
debug2('undoing /etc/hosts changes.')
rewrite_etc_hosts({}, port)
# Isolate function that needs to be replaced for tests
def setup_daemon():
if os.getuid() != 0:
raise Fatal('fw: '
'You must be root (or enable su/sudo) to set the firewall')
raise Fatal('You must be root (or enable su/sudo) to set the firewall')
# don't disappear if our controlling terminal or stdout/stderr
# disappears; we still have to clean up.
......@@ -99,10 +98,10 @@ def subnet_weight(s):
# supercede it in the transproxy list, at least, so the leftover rules
# are hopefully harmless.
def main(method_name, syslog):
helpers.logprefix = 'fw: '
stdin, stdout = setup_daemon()
hostmap = {}
helpers.logprefix = 'fw: '
debug1('Starting firewall with Python version %s\n'
debug1('Starting firewall with Python version %s'
% platform.python_version())
if method_name == "auto":
......@@ -119,7 +118,7 @@ def main(method_name, syslog):
"Check that the appropriate programs are in your "
"PATH." % method_name)
debug1('ready method name %s.\n' % method.name)
debug1('ready method name %s.' % method.name)
stdout.write('READY %s\n' % method.name)
stdout.flush()
......@@ -136,14 +135,14 @@ def main(method_name, syslog):
while 1:
line = stdin.readline(128)
if not line:
raise Fatal('fw: expected route but got %r' % line)
raise Fatal('expected route but got %r' % line)
elif line.startswith("NSLIST\n"):
break
try:
(family, width, exclude, ip, fport, lport) = \
line.strip().split(',', 5)
except BaseException:
raise Fatal('fw: expected route or NSLIST but got %r' % line)
raise Fatal('expected route or NSLIST but got %r' % line)
subnets.append((
int(family),
int(width),
......@@ -151,31 +150,31 @@ def main(method_name, syslog):
ip,
int(fport),
int(lport)))
debug2('Got subnets: %r\n' % subnets)
debug2('Got subnets: %r' % subnets)
nslist = []
if line != 'NSLIST\n':
raise Fatal('fw: expected NSLIST but got %r' % line)
raise Fatal('expected NSLIST but got %r' % line)
while 1:
line = stdin.readline(128)
if not line:
raise Fatal('fw: expected nslist but got %r' % line)
raise Fatal('expected nslist but got %r' % line)
elif line.startswith("PORTS "):
break
try:
(family, ip) = line.strip().split(',', 1)
except BaseException:
raise Fatal('fw: expected nslist or PORTS but got %r' % line)
raise Fatal('expected nslist or PORTS but got %r' % line)
nslist.append((int(family), ip))
debug2('Got partial nslist: %r\n' % nslist)
debug2('Got nslist: %r\n' % nslist)
debug2('Got partial nslist: %r' % nslist)
debug2('Got nslist: %r' % nslist)
if not line.startswith('PORTS '):
raise Fatal('fw: expected PORTS but got %r' % line)
raise Fatal('expected PORTS but got %r' % line)
_, _, ports = line.partition(" ")
ports = ports.split(",")
if len(ports) != 4:
raise Fatal('fw: expected 4 ports but got %d' % len(ports))
raise Fatal('expected 4 ports but got %d' % len(ports))
port_v6 = int(ports[0])
port_v4 = int(ports[1])
dnsport_v6 = int(ports[2])
......@@ -190,21 +189,21 @@ def main(method_name, syslog):
assert(dnsport_v4 >= 0)
assert(dnsport_v4 <= 65535)
debug2('Got ports: %d,%d,%d,%d\n'
debug2('Got ports: %d,%d,%d,%d'
% (port_v6, port_v4, dnsport_v6, dnsport_v4))
line = stdin.readline(128)
if not line:
raise Fatal('fw: expected GO but got %r' % line)
raise Fatal('expected GO but got %r' % line)
elif not line.startswith("GO "):
raise Fatal('fw: expected GO but got %r' % line)
raise Fatal('expected GO but got %r' % line)
_, _, args = line.partition(" ")
udp, user = args.strip().split(" ", 1)
udp = bool(int(udp))
if user == '-':
user = None
debug2('Got udp: %r, user: %r\n' % (udp, user))
debug2('Got udp: %r, user: %r' % (udp, user))
subnets_v6 = [i for i in subnets if i[0] == socket.AF_INET6]
nslist_v6 = [i for i in nslist if i[0] == socket.AF_INET6]
......@@ -212,17 +211,17 @@ def main(method_name, syslog):
nslist_v4 = [i for i in nslist if i[0] == socket.AF_INET]
try:
debug1('setting up.\n')
debug1('setting up.')
if subnets_v6 or nslist_v6:
debug2('setting up IPv6.\n')
debug2('setting up IPv6.')
method.setup_firewall(
port_v6, dnsport_v6, nslist_v6,
socket.AF_INET6, subnets_v6, udp,
user)
if subnets_v4 or nslist_v4:
debug2('setting up IPv4.\n')
debug2('setting up IPv4.')
method.setup_firewall(
port_v4, dnsport_v4, nslist_v4,
socket.AF_INET, subnets_v4, udp,
......@@ -245,40 +244,38 @@ def main(method_name, syslog):
if line.startswith('HOST '):
(name, ip) = line[5:].strip().split(',', 1)
hostmap[name] = ip
debug2('setting up /etc/hosts.\n')
debug2('setting up /etc/hosts.')
rewrite_etc_hosts(hostmap, port_v6 or port_v4)
elif line:
if not method.firewall_command(line):
raise Fatal('fw: expected command, got %r' % line)
raise Fatal('expected command, got %r' % line)
else:
break
finally:
try:
debug1('undoing changes.\n')
debug1('undoing changes.')
except BaseException:
debug2('An error occurred, ignoring it.')
try:
if subnets_v6 or nslist_v6:
debug2('undoing IPv6 changes.\n')
debug2('undoing IPv6 changes.')
method.restore_firewall(port_v6, socket.AF_INET6, udp, user)
except BaseException:
try:
debug1("Error trying to undo IPv6 firewall.\n")
for line in traceback.format_exc().splitlines():
debug1("---> %s\n" % line)
debug1("Error trying to undo IPv6 firewall.")
debug1(traceback.format_exc())
except BaseException:
debug2('An error occurred, ignoring it.')
try:
if subnets_v4 or nslist_v4:
debug2('undoing IPv4 changes.\n')
debug2('undoing IPv4 changes.')
method.restore_firewall(port_v4, socket.AF_INET, udp, user)
except BaseException:
try:
debug1("Error trying to undo IPv4 firewall.\n")
for line in traceback.format_exc().splitlines():
debug1("---> %s\n" % line)
debug1("Error trying to undo IPv4 firewall.")
debug1(traceback.format_exc())
except BaseException:
debug2('An error occurred, ignoring it.')
......@@ -287,8 +284,7 @@ def main(method_name, syslog):
restore_etc_hosts(hostmap, port_v6 or port_v4)
except BaseException:
try:
debug1("Error trying to undo /etc/hosts changes.\n")
for line in traceback.format_exc().splitlines():
debug1("---> %s\n" % line)
debug1("Error trying to undo /etc/hosts changes.")
debug1(traceback.format_exc())
except BaseException:
debug2('An error occurred, ignoring it.')
......@@ -15,12 +15,16 @@ def log(s):
global logprefix
try:
sys.stdout.flush()
# Put newline at end of string if line doesn't have one.
if not s.endswith("\n"):
s = s+"\n"
# Allow multi-line messages
if s.find("\n") != -1:
prefix = logprefix
s = s.rstrip("\n")
for line in s.split("\n"):
sys.stderr.write(prefix + line + "\n")
prefix = "---> "
prefix = " "
else:
sys.stderr.write(logprefix + s)
sys.stderr.flush()
......@@ -91,11 +95,11 @@ def resolvconf_nameservers(systemd_resolved):
words = line.lower().split()
if len(words) >= 2 and words[0] == 'nameserver':
this_file_nsservers.append(family_ip_tuple(words[1]))
debug2("Found DNS servers in %s: %s\n" %
debug2("Found DNS servers in %s: %s" %
(f, [n[1] for n in this_file_nsservers]))
nsservers += this_file_nsservers
except OSError as e:
debug3("Failed to read %s when looking for DNS servers: %s\n" %
debug3("Failed to read %s when looking for DNS servers: %s" %
(f, e.strerror))
return nsservers
......@@ -215,7 +219,7 @@ def which(file, mode=os.F_OK | os.X_OK):
path = get_path()
rv = _which(file, mode, path)
if rv:
debug2("which() found '%s' at %s\n" % (file, rv))
debug2("which() found '%s' at %s" % (file, rv))
else:
debug2("which() could not find '%s' in %s\n" % (file, path))
debug2("which() could not find '%s' in %s" % (file, path))
return rv
......@@ -24,7 +24,7 @@ try:
null = open(os.devnull, 'wb')
except IOError:
_, e = sys.exc_info()[:2]
log('warning: %s\n' % e)
log('warning: %s' % e)
null = os.popen("sh -c 'while read x; do :; done'", 'wb', 4096)
......@@ -80,13 +80,13 @@ def found_host(name, ip):
oldip = hostnames.get(name)
if oldip != ip:
hostnames[name] = ip
debug1('Found: %s: %s\n' % (name, ip))
debug1('Found: %s: %s' % (name, ip))
sys.stdout.write('%s,%s\n' % (name, ip))
write_host_cache()
def _check_etc_hosts():
debug2(' > hosts\n')
debug2(' > hosts')
for line in open('/etc/hosts'):
line = re.sub(r'#.*', '', line)
words = line.strip().split()
......@@ -95,17 +95,17 @@ def _check_etc_hosts():
ip = words[0]
names = words[1:]
if _is_ip(ip):
debug3('< %s %r\n' % (ip, names))
debug3('< %s %r' % (ip, names))
for n in names:
check_host(n)
found_host(n, ip)
def _check_revdns(ip):
debug2(' > rev: %s\n' % ip)
debug2(' > rev: %s' % ip)
try:
r = socket.gethostbyaddr(ip)
debug3('< %s\n' % r[0])
debug3('< %s' % r[0])
check_host(r[0])
found_host(r[0], ip)
except (socket.herror, UnicodeError):
......@@ -113,10 +113,10 @@ def _check_revdns(ip):
def _check_dns(hostname):
debug2(' > dns: %s\n' % hostname)
debug2(' > dns: %s' % hostname)
try:
ip = socket.gethostbyname(hostname)
debug3('< %s\n' % ip)
debug3('< %s' % ip)
check_host(ip)
found_host(hostname, ip)
except (socket.gaierror, UnicodeError):
......@@ -124,7 +124,7 @@ def _check_dns(hostname):
def _check_netstat():
debug2(' > netstat\n')
debug2(' > netstat')
argv = ['netstat', '-n']
try:
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null,
......@@ -133,11 +133,11 @@ def _check_netstat():
p.wait()
except OSError:
_, e = sys.exc_info()[:2]
log('%r failed: %r\n' % (argv, e))
log('%r failed: %r' % (argv, e))
return
for ip in re.findall(r'\d+\.\d+\.\d+\.\d+', content):
debug3('< %s\n' % ip)
debug3('< %s' % ip)
check_host(ip)
......@@ -146,7 +146,7 @@ def _check_smb(hostname):
global _smb_ok
if not _smb_ok:
return
debug2(' > smb: %s\n' % hostname)
debug2(' > smb: %s' % hostname)
argv = ['smbclient', '-U', '%', '-L', hostname]
try:
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null,
......@@ -155,7 +155,7 @@ def _check_smb(hostname):
p.wait()
except OSError:
_, e = sys.exc_info()[:2]
log('%r failed: %r\n' % (argv, e))
log('%r failed: %r' % (argv, e))
_smb_ok = False
return
......@@ -178,7 +178,7 @@ def _check_smb(hostname):
break
words = line.split()
hostname = words[0].lower()
debug3('< %s\n' % hostname)
debug3('< %s' % hostname)
check_host(hostname)
# workgroup list section:
......@@ -192,7 +192,7 @@ def _check_smb(hostname):
break
words = line.split()
(workgroup, hostname) = (words[0].lower(), words[1].lower())
debug3('< group(%s) -> %s\n' % (workgroup, hostname))
debug3('< group(%s) -> %s' % (workgroup, hostname))
check_host(hostname)
check_workgroup(workgroup)
......@@ -205,7 +205,7 @@ def _check_nmb(hostname, is_workgroup, is_master):
global _nmb_ok
if not _nmb_ok:
return
debug2(' > n%d%d: %s\n' % (is_workgroup, is_master, hostname))
debug2(' > n%d%d: %s' % (is_workgroup, is_master, hostname))
argv = ['nmblookup'] + ['-M'] * is_master + ['--', hostname]
try:
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null,
......@@ -214,18 +214,18 @@ def _check_nmb(hostname, is_workgroup, is_master):
rv = p.wait()
except OSError:
_, e = sys.exc_info()[:2]
log('%r failed: %r\n' % (argv, e))
log('%r failed: %r' % (argv, e))
_nmb_ok = False
return
if rv:
log('%r returned %d\n' % (argv, rv))
log('%r returned %d' % (argv, rv))
return
for line in lines:
m = re.match(r'(\d+\.\d+\.\d+\.\d+) (\w+)<\w\w>\n', line)
if m:
g = m.groups()
(ip, name) = (g[0], g[1].lower())
debug3('< %s -> %s\n' % (name, ip))
debug3('< %s -> %s' % (name, ip))
if is_workgroup:
_enqueue(_check_smb, ip)
else:
......@@ -263,12 +263,9 @@ def _stdin_still_ok(timeout):
def hw_main(seed_hosts, auto_hosts):
if helpers.verbose >= 2:
helpers.logprefix = 'HH: '
else:
helpers.logprefix = 'hostwatch: '
debug1('Starting hostwatch with Python version %s\n'
debug1('Starting hostwatch with Python version %s'
% platform.python_version())
for h in seed_hosts:
......
......@@ -7,7 +7,7 @@ def nonfatal(func, *args):
try:
func(*args)
except Fatal as e:
log('fw: error: %s\n' % e)
log('error: %s' % e)
def ipt_chain_exists(family, table, name):
......@@ -24,7 +24,7 @@ def ipt_chain_exists(family, table, name):
if line.startswith('Chain %s ' % name):
return True
except ssubprocess.CalledProcessError as e:
raise Fatal('fw: %r returned %d' % (argv, e.returncode))
raise Fatal('%r returned %d' % (argv, e.returncode))
def ipt(family, table, *args):
......@@ -34,10 +34,10 @@ def ipt(family, table, *args):
argv = ['iptables', '-t', table] + list(args)
else:
raise Exception('Unsupported family "%s"' % family_to_string(family))
debug1('%s\n' % ' '.join(argv))
debug1('%s' % ' '.join(argv))
rv = ssubprocess.call(argv, env=get_env())
if rv:
raise Fatal('fw: %r returned %d' % (argv, rv))
raise Fatal('%r returned %d' % (argv, rv))
def nft(family, table, action, *args):
......@@ -45,10 +45,10 @@ def nft(family, table, action, *args):
argv = ['nft', action, 'inet', table] + list(args)
else:
raise Exception('Unsupported family "%s"' % family_to_string(family))
debug1('%s\n' % ' '.join(argv))
debug1('%s' % ' '.join(argv))
rv = ssubprocess.call(argv, env=get_env())
if rv:
raise Fatal('fw: %r returned %d' % (argv, rv))
raise Fatal('%r returned %d' % (argv, rv))
_no_ttl_module = False
......@@ -66,8 +66,8 @@ def ipt_ttl(family, *args):
except Fatal:
ipt(family, *args)
# we only get here if the non-ttl attempt succeeds
log('fw: WARNING: your iptables is missing '
'the ttl module.\n')
log('WARNING: your iptables is missing '
'the ttl module.')
_no_ttl_module = True
else:
ipt(family, *args)
......@@ -66,7 +66,7 @@ class BaseMethod(object):
@staticmethod
def recv_udp(udp_listener, bufsize):
debug3('Accept UDP using recvfrom.\n')
debug3('Accept UDP using recvfrom.')
data, srcip = udp_listener.recvfrom(bufsize)
return (srcip, None, data)
......@@ -87,7 +87,7 @@ class BaseMethod(object):
for key in ["udp", "dns", "ipv6", "ipv4", "user"]:
if getattr(features, key) and not getattr(avail, key):
raise Fatal(
"Feature %s not supported with method %s.\n" %
"Feature %s not supported with method %s." %
(key, self.name))
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
......@@ -108,13 +108,13 @@ def get_method(method_name):
def get_auto_method():
debug3("Selecting a method automatically...\n")
debug3("Selecting a method automatically...")
# Try these methods, in order:
methods_to_try = ["nat", "nft", "pf", "ipfw"]
for m in methods_to_try:
method = get_method(m)
if method.is_supported():
debug3("Method '%s' was automatically selected.\n" % m)
debug3("Method '%s' was automatically selected." % m)
return method
raise Fatal("Unable to automatically find a supported method. Check that "
......
......@@ -28,7 +28,7 @@ IPV6_RECVDSTADDR = 74
if recvmsg == "python":
def recv_udp(listener, bufsize):
debug3('Accept UDP python using recvmsg.\n')
debug3('Accept UDP python using recvmsg.')
data, ancdata, _, srcip = listener.recvmsg(4096,
socket.CMSG_SPACE(4))
dstip = None
......@@ -41,7 +41,7 @@ if recvmsg == "python":
return (srcip, dstip, data)
elif recvmsg == "socket_ext":
def recv_udp(listener, bufsize):
debug3('Accept UDP using socket_ext recvmsg.\n')
debug3('Accept UDP using socket_ext recvmsg.')
srcip, data, adata, _ = listener.recvmsg((bufsize,),
socket.CMSG_SPACE(4))
dstip = None
......@@ -54,7 +54,7 @@ elif recvmsg == "socket_ext":
return (srcip, dstip, data[0])
else:
def recv_udp(listener, bufsize):
debug3('Accept UDP using recvfrom.\n')
debug3('Accept UDP using recvfrom.')
data, srcip = listener.recvfrom(bufsize)
return (srcip, None, data)
......@@ -67,7 +67,7 @@ def ipfw_rule_exists(n):
for line in p.stdout:
if line.startswith(b'%05d ' % n):
if not ('ipttl 63' in line or 'check-state' in line):
log('non-sshuttle ipfw rule: %r\n' % line.strip())
log('non-sshuttle ipfw rule: %r' % line.strip())
raise Fatal('non-sshuttle ipfw rule #%d already exists!' % n)
found = True
rv = p.wait()
......@@ -96,7 +96,7 @@ def _fill_oldctls(prefix):
def _sysctl_set(name, val):
argv = ['sysctl', '-w', '%s=%s' % (name, val)]
debug1('>> %s\n' % ' '.join(argv))
debug1('>> %s' % ' '.join(argv))
return ssubprocess.call(argv, stdout=open(os.devnull, 'w'), env=get_env())
# No env: No output. (Or error that won't be parsed.)
......@@ -111,13 +111,13 @@ def sysctl_set(name, val, permanent=False):
if not _oldctls:
_fill_oldctls(PREFIX)
if not (name in _oldctls):
debug1('>> No such sysctl: %r\n' % name)
debug1('>> No such sysctl: %r' % name)
return False
oldval = _oldctls[name]
if val != oldval:
rv = _sysctl_set(name, val)
if rv == 0 and permanent:
debug1('>> ...saving permanently in /etc/sysctl.conf\n')
debug1('>> ...saving permanently in /etc/sysctl.conf')
f = open('/etc/sysctl.conf', 'a')
f.write('\n'
'# Added by sshuttle\n'
......@@ -130,7 +130,7 @@ def sysctl_set(name, val, permanent=False):
def ipfw(*args):
argv = ['ipfw', '-q'] + list(args)
debug1('>> %s\n' % ' '.join(argv))
debug1('>> %s' % ' '.join(argv))
rv = ssubprocess.call(argv, env=get_env())
# No env: No output. (Or error that won't be parsed.)
if rv:
......@@ -139,7 +139,7 @@ def ipfw(*args):
def ipfw_noexit(*args):
argv = ['ipfw', '-q'] + list(args)
debug1('>> %s\n' % ' '.join(argv))
debug1('>> %s' % ' '.join(argv))
ssubprocess.call(argv, env=get_env())
# No env: No output. (Or error that won't be parsed.)
......@@ -161,7 +161,7 @@ class Method(BaseMethod):
if not dstip:
debug1(
"-- ignored UDP from %r: "
"couldn't determine destination IP address\n" % (srcip,))
"couldn't determine destination IP address" % (srcip,))
return None
return srcip, dstip, data
......@@ -169,10 +169,10 @@ class Method(BaseMethod):
if not srcip:
debug1(
"-- ignored UDP to %r: "
"couldn't determine source IP address\n" % (dstip,))
"couldn't determine source IP address" % (dstip,))
return
# debug3('Sending SRC: %r DST: %r\n' % (srcip, dstip))
# debug3('Sending SRC: %r DST: %r' % (srcip, dstip))
sender = socket.socket(sock.family, socket.SOCK_DGRAM)
sender.setsockopt(socket.SOL_IP, IP_BINDANY, 1)
sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
......@@ -258,5 +258,5 @@ class Method(BaseMethod):
if which("ipfw"):
return True
debug2("ipfw method not supported because 'ipfw' command is "
"missing.\n")
"missing.")
return False
......@@ -129,5 +129,5 @@ class Method(BaseMethod):
if which("iptables"):
return True
debug2("nat method not supported because 'iptables' command "
"is missing.\n")
"is missing.")
return False
......@@ -118,5 +118,5 @@ class Method(BaseMethod):
def is_supported(self):
if which("nft"):
return True
debug2("nft method not supported because 'nft' command is missing.\n")
debug2("nft method not supported because 'nft' command is missing.")
return False
......@@ -386,7 +386,7 @@ else:
def pfctl(args, stdin=None):
argv = ['pfctl'] + shlex.split(args)
debug1('>> %s\n' % ' '.join(argv))
debug1('>> %s' % ' '.join(argv))
p = ssubprocess.Popen(argv, stdin=ssubprocess.PIPE,
stdout=ssubprocess.PIPE,
stderr=ssubprocess.PIPE,
......@@ -495,5 +495,5 @@ class Method(BaseMethod):
def is_supported(self):
if which("pfctl"):
return True
debug2("pf method not supported because 'pfctl' command is missing.\n")
debug2("pf method not supported because 'pfctl' command is missing.")
return False
......@@ -32,7 +32,7 @@ IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR
if recvmsg == "python":
def recv_udp(listener, bufsize):
debug3('Accept UDP python using recvmsg.\n')
debug3('Accept UDP python using recvmsg.')
data, ancdata, _, srcip = listener.recvmsg(
4096, socket.CMSG_SPACE(24))
dstip = None
......@@ -63,7 +63,7 @@ if recvmsg == "python":
return (srcip, dstip, data)
elif recvmsg == "socket_ext":
def recv_udp(listener, bufsize):
debug3('Accept UDP using socket_ext recvmsg.\n')
debug3('Accept UDP using socket_ext recvmsg.')
srcip, data, adata, _ = listener.recvmsg(
(bufsize,), socket.CMSG_SPACE(24))
dstip = None
......@@ -96,7 +96,7 @@ elif recvmsg == "socket_ext":
return (srcip, dstip, data[0])
else:
def recv_udp(listener, bufsize):
debug3('Accept UDP using recvfrom.\n')
debug3('Accept UDP using recvfrom.')
data, srcip = listener.recvfrom(bufsize)
return (srcip, None, data)
......
......@@ -26,7 +26,7 @@ def _notify(message):
try:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
except (OSError, IOError) as e:
debug1("Error creating socket to notify systemd: %s\n" % e)
debug1("Error creating socket to notify systemd: %s" % e)
return False
if not message:
......@@ -37,7 +37,7 @@ def _notify(message):
try:
return (sock.sendto(message, addr) > 0)
except (OSError, IOError) as e:
debug1("Error notifying systemd: %s\n" % e)
debug1("Error notifying systemd: %s" % e)
return False
......
......@@ -96,7 +96,7 @@ def _list_routes(argv, extract_route):
(socket.AF_INET, socket.inet_ntoa(struct.pack('!I', ip)), width))
rv = p.wait()
if rv != 0:
log('WARNING: %r returned %d\n' % (argv, rv))
log('WARNING: %r returned %d' % (argv, rv))
return routes
......@@ -108,7 +108,7 @@ def list_routes():
routes = _list_routes(['netstat', '-rn'], _route_netstat)
else:
log('WARNING: Neither "ip" nor "netstat" were found on the server. '
'--auto-nets feature will not work.\n')
'--auto-nets feature will not work.')
routes = []
for (family, ip, width) in routes:
......@@ -135,7 +135,7 @@ def start_hostwatch(seed_hosts, auto_hosts):
s1.close()
rv = hostwatch.hw_main(seed_hosts, auto_hosts) or 0
except Exception:
log('%s\n' % _exc_dump())
log('%s' % _exc_dump())
rv = 98
finally:
os._exit(rv)
......@@ -196,7 +196,7 @@ class DnsProxy(Handler):
self.peers[sock] = peer
debug2('DNS: sending to %r:%d (try %d)\n' % (peer, port, self.tries))
debug2('DNS: sending to %r:%d (try %d)' % (peer, port, self.tries))
try:
sock.send(self.request)
self.socks.append(sock)
......@@ -206,11 +206,11 @@ class DnsProxy(Handler):
# might have been spurious; try again.
# Note: these errors sometimes are reported by recv(),
# and sometimes by send(). We have to catch both.
debug2('DNS send to %r: %s\n' % (peer, e))
debug2('DNS send to %r: %s' % (peer, e))
self.try_send()
return
else:
log('DNS send to %r: %s\n' % (peer, e))
log('DNS send to %r: %s' % (peer, e))
return
def callback(self, sock):
......@@ -227,13 +227,13 @@ class DnsProxy(Handler):
# might have been spurious; try again.
# Note: these errors sometimes are reported by recv(),
# and sometimes by send(). We have to catch both.
debug2('DNS recv from %r: %s\n' % (peer, e))
debug2('DNS recv from %r: %s' % (peer, e))
self.try_send()
return
else:
log('DNS recv from %r: %s\n' % (peer, e))
log('DNS recv from %r: %s' % (peer, e))
return
debug2('DNS response: %d bytes\n' % len(data))
debug2('DNS response: %d bytes' % len(data))
self.mux.send(self.chan, ssnet.CMD_DNS_RESPONSE, data)
self.ok = False
......@@ -251,12 +251,12 @@ class UdpProxy(Handler):
self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, 63)
def send(self, dstip, data):
debug2(' s: UDP: sending to %r port %d\n' % dstip)
debug2('UDP: sending to %r port %d' % dstip)
try:
self.sock.sendto(data, dstip)
except socket.error:
_, e = sys.exc_info()[:2]
log(' s: UDP send to %r port %d: %s\n' % (dstip[0], dstip[1], e))
log('UDP send to %r port %d: %s' % (dstip[0], dstip[1], e))
return
def callback(self, sock):
......@@ -264,19 +264,19 @@ class UdpProxy(Handler):
data, peer = sock.recvfrom(4096)
except socket.error:
_, e = sys.exc_info()[:2]
log(' s: UDP recv from %r port %d: %s\n' % (peer[0], peer[1], e))
log('UDP recv from %r port %d: %s' % (peer[0], peer[1], e))
return
debug2(' s: UDP response: %d bytes\n' % len(data))
debug2('UDP response: %d bytes' % len(data))
hdr = b("%s,%r," % (peer[0], peer[1]))
self.mux.send(self.chan, ssnet.CMD_UDP_DATA, hdr + data)
def main(latency_control, auto_hosts, to_nameserver, auto_nets):
debug1(' s: Starting server with Python version %s\n'
% platform.python_version())
helpers.logprefix = ' s: '
debug1('latency control setting = %r\n' % latency_control)
debug1('Starting server with Python version %s'
% platform.python_version())
debug1('latency control setting = %r' % latency_control)
# synchronization header
sys.stdout.write('\0\0SSHUTTLE0001')
......@@ -286,12 +286,12 @@ def main(latency_control, auto_hosts, to_nameserver, auto_nets):
mux = Mux(sys.stdin, sys.stdout)
handlers.append(mux)
debug1('auto-nets:' + str(auto_nets) + '\n')
debug1('auto-nets:' + str(auto_nets))
if auto_nets:
routes = list(list_routes())
debug1('available routes:\n')
debug1('available routes:')
for r in routes:
debug1(' %d/%s/%d\n' % r)
debug1(' %d/%s/%d' % r)
else:
routes = []
......@@ -316,7 +316,7 @@ def main(latency_control, auto_hosts, to_nameserver, auto_nets):
hw.leftover = b('')
mux.send(0, ssnet.CMD_HOST_LIST, b('\n').join(lines))
else:
raise Fatal(' s: hostwatch process died')
raise Fatal('hostwatch process died')
def got_host_req(data):
if not hw.pid:
......@@ -343,7 +343,7 @@ def main(latency_control, auto_hosts, to_nameserver, auto_nets):
dnshandlers = {}
def dns_req(channel, data):
debug2('Incoming DNS request channel=%d.\n' % channel)
debug2('Incoming DNS request channel=%d.' % channel)
h = DnsProxy(mux, channel, data, to_nameserver)
handlers.append(h)
dnshandlers[channel] = h
......@@ -352,25 +352,25 @@ def main(latency_control, auto_hosts, to_nameserver, auto_nets):
udphandlers = {}
def udp_req(channel, cmd, data):
debug2('Incoming UDP request channel=%d, cmd=%d\n' % (channel, cmd))
debug2('Incoming UDP request channel=%d, cmd=%d' % (channel, cmd))
if cmd == ssnet.CMD_UDP_DATA:
(dstip, dstport, data) = data.split(b(','), 2)
dstport = int(dstport)
debug2('is incoming UDP data. %r %d.\n' % (dstip, dstport))
debug2('is incoming UDP data. %r %d.' % (dstip, dstport))
h = udphandlers[channel]
h.send((dstip, dstport), data)
elif cmd == ssnet.CMD_UDP_CLOSE:
debug2('is incoming UDP close\n')
debug2('is incoming UDP close')
h = udphandlers[channel]
h.ok = False
del mux.channels[channel]
def udp_open(channel, data):
debug2('Incoming UDP open.\n')
debug2('Incoming UDP open.')
family = int(data)
mux.channels[channel] = lambda cmd, data: udp_req(channel, cmd, data)
if channel in udphandlers:
raise Fatal(' s: UDP connection channel %d already open' % channel)
raise Fatal('UDP connection channel %d already open' % channel)
else:
h = UdpProxy(mux, channel, family)
handlers.append(h)
......@@ -383,7 +383,7 @@ def main(latency_control, auto_hosts, to_nameserver, auto_nets):
(rpid, rv) = os.waitpid(hw.pid, os.WNOHANG)
if rpid:
raise Fatal(
'hostwatch exited unexpectedly: code 0x%04x\n' % rv)
'hostwatch exited unexpectedly: code 0x%04x' % rv)
ssnet.runonce(handlers, mux)
if latency_control:
......@@ -394,7 +394,7 @@ def main(latency_control, auto_hosts, to_nameserver, auto_nets):
remove = []
for channel, h in dnshandlers.items():
if h.timeout < now or not h.ok:
debug3('expiring dnsreqs channel=%d\n' % channel)
debug3('expiring dnsreqs channel=%d' % channel)
remove.append(channel)
h.ok = False
for channel in remove:
......@@ -403,7 +403,7 @@ def main(latency_control, auto_hosts, to_nameserver, auto_nets):
remove = []
for channel, h in udphandlers.items():
if not h.ok:
debug3('expiring UDP channel=%d\n' % channel)
debug3('expiring UDP channel=%d' % channel)
remove.append(channel)
h.ok = False
for channel in remove:
......
......@@ -160,7 +160,7 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
s1a, s1b = os.dup(s1.fileno()), os.dup(s1.fileno())
s1.close()
debug2('executing: %r\n' % argv)
debug2('executing: %r' % argv)
p = ssubprocess.Popen(argv, stdin=s1a, stdout=s1b, preexec_fn=setup,
close_fds=True, stderr=stderr)
os.close(s1a)
......
......@@ -83,7 +83,7 @@ def _nb_clean(func, *args):
if e.errno not in (errno.EWOULDBLOCK, errno.EAGAIN):
raise
else:
debug3('%s: err was: %s\n' % (func.__name__, e))
debug3('%s: err was: %s' % (func.__name__, e))
return None
......@@ -111,7 +111,7 @@ class SockWrapper:
def __init__(self, rsock, wsock, connect_to=None, peername=None):
global _swcount
_swcount += 1
debug3('creating new SockWrapper (%d now exist)\n' % _swcount)
debug3('creating new SockWrapper (%d now exist)' % _swcount)
self.exc = None
self.rsock = rsock
self.wsock = wsock
......@@ -124,9 +124,9 @@ class SockWrapper:
def __del__(self):
global _swcount
_swcount -= 1
debug1('%r: deleting (%d remain)\n' % (self, _swcount))
debug1('%r: deleting (%d remain)' % (self, _swcount))
if self.exc:
debug1('%r: error was: %s\n' % (self, self.exc))
debug1('%r: error was: %s' % (self, self.exc))
def __repr__(self):
if self.rsock == self.wsock:
......@@ -148,14 +148,14 @@ class SockWrapper:
if not self.connect_to:
return # already connected
self.rsock.setblocking(False)
debug3('%r: trying connect to %r\n' % (self, self.connect_to))
debug3('%r: trying connect to %r' % (self, self.connect_to))
try:
self.rsock.connect(self.connect_to)
# connected successfully (Linux)
self.connect_to = None
except socket.error:
_, e = sys.exc_info()[:2]
debug3('%r: connect result: %s\n' % (self, e))
debug3('%r: connect result: %s' % (self, e))
if e.args[0] == errno.EINVAL:
# this is what happens when you call connect() on a socket
# that is now connected but returned EINPROGRESS last time,
......@@ -165,7 +165,7 @@ class SockWrapper:
realerr = self.rsock.getsockopt(socket.SOL_SOCKET,
socket.SO_ERROR)
e = socket.error(realerr, os.strerror(realerr))
debug3('%r: fixed connect result: %s\n' % (self, e))
debug3('%r: fixed connect result: %s' % (self, e))
if e.args[0] in [errno.EINPROGRESS, errno.EALREADY]:
pass # not connected yet
elif e.args[0] == 0:
......@@ -191,13 +191,13 @@ class SockWrapper:
def noread(self):
if not self.shut_read:
debug2('%r: done reading\n' % self)
debug2('%r: done reading' % self)
self.shut_read = True
# self.rsock.shutdown(SHUT_RD) # doesn't do anything anyway
def nowrite(self):
if not self.shut_write:
debug2('%r: done writing\n' % self)
debug2('%r: done writing' % self)
self.shut_write = True
try:
self.wsock.shutdown(SHUT_WR)
......@@ -218,7 +218,7 @@ class SockWrapper:
except OSError:
_, e = sys.exc_info()[:2]
if e.errno == errno.EPIPE:
debug1('%r: uwrite: got EPIPE\n' % self)
debug1('%r: uwrite: got EPIPE' % self)
self.nowrite()
return 0
else:
......@@ -275,12 +275,12 @@ class Handler:
_add(r, i)
def callback(self, sock):
log('--no callback defined-- %r\n' % self)
log('--no callback defined-- %r' % self)
(r, _, _) = select.select(self.socks, [], [], 0)
for s in r:
v = s.recv(4096)
if not v:
log('--closed-- %r\n' % self)
log('--closed-- %r' % self)
self.socks = []
self.ok = False
......@@ -377,7 +377,7 @@ class Mux(Handler):
# for b in self.outbuf:
# (s1,s2,c) = struct.unpack('!ccH', b[:4])
# ob.append(c)
# log('outbuf: %d %r\n' % (self.amount_queued(), ob))
# log('outbuf: %d %r' % (self.amount_queued(), ob))
def send(self, channel, cmd, data):
assert isinstance(data, bytes)
......@@ -385,18 +385,18 @@ class Mux(Handler):
p = struct.pack('!ccHHH', b('S'), b('S'), channel, cmd, len(data)) \
+ data
self.outbuf.append(p)
debug2(' > channel=%d cmd=%s len=%d (fullness=%d)\n'
debug2(' > channel=%d cmd=%s len=%d (fullness=%d)'
% (channel, cmd_to_name.get(cmd, hex(cmd)),
len(data), self.fullness))
self.fullness += len(data)
def got_packet(self, channel, cmd, data):
debug2('< channel=%d cmd=%s len=%d\n'
debug2('< channel=%d cmd=%s len=%d'
% (channel, cmd_to_name.get(cmd, hex(cmd)), len(data)))
if cmd == CMD_PING:
self.send(0, CMD_PONG, data)
elif cmd == CMD_PONG:
debug2('received PING response\n')
debug2('received PING response')
self.too_full = False
self.fullness = 0
elif cmd == CMD_EXIT:
......@@ -431,7 +431,7 @@ class Mux(Handler):
else:
callback = self.channels.get(channel)
if not callback:
log('warning: closed channel %d got cmd=%s len=%d\n'
log('warning: closed channel %d got cmd=%s len=%d'
% (channel, cmd_to_name.get(cmd, hex(cmd)), len(data)))
else:
callback(cmd, data)
......@@ -446,7 +446,7 @@ class Mux(Handler):
flags = fcntl.fcntl(self.wfile.fileno(), fcntl.F_SETFL, flags)
if self.outbuf and self.outbuf[0]:
wrote = _nb_clean(os.write, self.wfile.fileno(), self.outbuf[0])
debug2('mux wrote: %r/%d\n' % (wrote, len(self.outbuf[0])))
debug2('mux wrote: %r/%d' % (wrote, len(self.outbuf[0])))
if wrote:
self.outbuf[0] = self.outbuf[0][wrote:]
while self.outbuf and not self.outbuf[0]:
......@@ -465,7 +465,7 @@ class Mux(Handler):
except OSError:
_, e = sys.exc_info()[:2]
raise Fatal('other end: %r' % e)
# log('<<< %r\n' % b)
# log('<<< %r' % b)
if read == b(''): # EOF
self.ok = False
if read:
......@@ -473,7 +473,7 @@ class Mux(Handler):
def handle(self):
self.fill()
# log('inbuf is: (%d,%d) %r\n'
# log('inbuf is: (%d,%d) %r'
# % (self.want, len(self.inbuf), self.inbuf))
while 1:
if len(self.inbuf) >= (self.want or HDR_LEN):
......@@ -511,7 +511,7 @@ class MuxWrapper(SockWrapper):
self.channel = channel
self.mux.channels[channel] = self.got_packet
self.socks = []
debug2('new channel: %d\n' % channel)
debug2('new channel: %d' % channel)
def __del__(self):
self.nowrite()
......@@ -527,7 +527,7 @@ class MuxWrapper(SockWrapper):
def setnoread(self):
if not self.shut_read:
debug2('%r: done reading\n' % self)
debug2('%r: done reading' % self)
self.shut_read = True
self.maybe_close()
......@@ -538,13 +538,13 @@ class MuxWrapper(SockWrapper):
def setnowrite(self):
if not self.shut_write:
debug2('%r: done writing\n' % self)
debug2('%r: done writing' % self)
self.shut_write = True
self.maybe_close()
def maybe_close(self):
if self.shut_read and self.shut_write:
debug2('%r: closing connection\n' % self)
debug2('%r: closing connection' % self)
# remove the mux's reference to us. The python garbage collector
# will then be able to reap our object.
self.mux.channels[self.channel] = None
......@@ -581,7 +581,7 @@ class MuxWrapper(SockWrapper):
def connect_dst(family, ip, port):
debug2('Connecting to %s:%d\n' % (ip, port))
debug2('Connecting to %s:%d' % (ip, port))
outsock = socket.socket(family)
outsock.setsockopt(socket.SOL_IP, socket.IP_TTL, 63)
return SockWrapper(outsock, outsock,
......@@ -599,11 +599,11 @@ def runonce(handlers, mux):
for s in handlers:
s.pre_select(r, w, x)
debug2('Waiting: %d r=%r w=%r x=%r (fullness=%d/%d)\n'
debug2('Waiting: %d r=%r w=%r x=%r (fullness=%d/%d)'
% (len(handlers), _fds(r), _fds(w), _fds(x),
mux.fullness, mux.too_full))
(r, w, x) = select.select(r, w, x)
debug2(' Ready: %d r=%r w=%r x=%r\n'
debug2(' Ready: %d r=%r w=%r x=%r'
% (len(handlers), _fds(r), _fds(w), _fds(x)))
ready = r + w + x
did = {}
......
......@@ -45,11 +45,11 @@ def save_config(content, file_name):
returncode = process.returncode
if returncode:
log('Failed updating sudoers file.\n')
log('Failed updating sudoers file.')
debug1(streamdata)
exit(returncode)
else:
log('Success, sudoers file update.\n')
log('Success, sudoers file update.')
exit(0)
......
......@@ -24,19 +24,19 @@ def test_log(mock_stderr, mock_stdout):
call.flush(),
]
assert mock_stderr.mock_calls == [
call.write('prefix: message'),
call.write('prefix: message\n'),
call.flush(),
call.write('prefix: abc'),
call.write('prefix: abc\n'),
call.flush(),
call.write('prefix: message 1\n'),
call.flush(),
call.write('prefix: message 2\n'),
call.write('---> line2\n'),
call.write('---> line3\n'),
call.write(' line2\n'),
call.write(' line3\n'),
call.flush(),
call.write('prefix: message 3\n'),
call.write('---> line2\n'),
call.write('---> line3\n'),
call.write(' line2\n'),
call.write(' line3\n'),
call.flush(),
]
......@@ -51,7 +51,7 @@ def test_debug1(mock_stderr, mock_stdout):
call.flush(),
]
assert mock_stderr.mock_calls == [
call.write('prefix: message'),
call.write('prefix: message\n'),
call.flush(),
]
......@@ -76,7 +76,7 @@ def test_debug2(mock_stderr, mock_stdout):
call.flush(),
]
assert mock_stderr.mock_calls == [
call.write('prefix: message'),
call.write('prefix: message\n'),
call.flush(),
]
......@@ -101,7 +101,7 @@ def test_debug3(mock_stderr, mock_stdout):
call.flush(),
]
assert mock_stderr.mock_calls == [
call.write('prefix: message'),
call.write('prefix: message\n'),
call.flush(),
]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment