Compare commits

..

No commits in common. "master" and "v1.0" have entirely different histories.

7 changed files with 102 additions and 306 deletions

View file

@ -1,38 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View file

@ -4,8 +4,3 @@ E:nojhan@nojhan.net
D:2009-06-23
C:Initial code, lead developper
N:Ghislain Picard
P:ghislainp
E:ghislain.picard@univ-grenoble-alpes.fr
D:2021-01-22
C:Fixes on tunnels detection

24
CHANGELOG Normal file
View file

@ -0,0 +1,24 @@
0.5:
* python3
* complete rewrite for portability
* handle autossh tunnels *and* raw ssh tunnels
* better formatting
0.4:
* adds IPv6 support
* bugfixes
0.3:
* added a via_host field (show on which host the tunnel is build)
* don't try to show connections if the user is not root
0.2:
* update from the deprecated popen3 functions to the subprocess module (need python >= 2.4)
* html help page
0.1:
* command line interface
* curses interface
* list of active autossh instances
* associated active ssh connections

View file

@ -1,34 +0,0 @@
1.1: "Ñìrikarñar"
- handle local, remote and dynamic port forwading tunnels,
- different colors for different types.
1.0: "Ereshkigal"
- python 3.8,
- fix tunnels detection,
- fix logging,
- code formating.
0.5:
- python3,
- complete rewrite for portability,
- handle autossh tunnels *and* raw ssh tunnels,
- better formatting.
0.4:
- adds IPv6 support,
- bugfixes.
0.3:
- added a via_host field (show on which host the tunnel is build),
- don't try to show connections if the user is not root.
0.2:
- update from the deprecated popen3 functions to the subprocess module (need python >= 2.4),
- html help page.
0.1:
- command line interface,
- curses interface,
- list of active autossh instances,
- associated active ssh connections.

View file

@ -5,27 +5,23 @@ tunnelmon -- Monitor and manage autoSSH tunnels
`tunnelmon` [-h]
`tunnelmon` [-c] [-n] [-u] [-l LEVEL] [-g FILE] [-s]
`tunnelmon` [-c] [-n] [-u] [-l LEVEL] [-g FILE]
## DESCRIPTION
`tunnelmon` is an autossh tunnel monitor. It gives a user interface to monitor existing SSH tunnel, and tunnels managed with autossh.
`tunnelmon` is an autossh tunnel monitor. It gives a user interface to monitor existing SSH tunnel that are managed with autossh.
It can print the current state of your tunnels or display them in an interactive text-based interface.
`tunnelmon` is released under the GNU Public License v3.
![Screenshot](https://raw.github.com/nojhan/tunnelmon/master/screenshot.png)
## INSTALLATION
`tunnelmon` targets Linux operating systems, and depends on:
* `openssh-client`,
* `python` version 3.8 at least, you may also need to install the following python modules (for example via `pip`, but you may use any other package management system going along with your installation):
* `psutils`
* `curses`
* `openssh-client`
* `python` version 3.8 at least.
You may also want to install the recommend packages:
* `autossh`
@ -55,9 +51,6 @@ Called without option,`tunnelmon` will print the current state of the autossh tu
Log messages are written to the given FILE. Useful to debug the interactive interface.
If not set, asking for the curses interface automatically set logging to the "tunnelmon.log" file.
* `-s`, `--log-sensitive`:
Allow sensitive information (hostnames, IPs, PIDs, etc.) into the logs.
## INTERACTIVE INTERFACE
@ -67,31 +60,7 @@ Keyboard commands:
* `R`: Reload the selected autossh instance (i.e. send a `SIGUSR1`, which is interpreted as a reload command by autossh).
* `C`: Close the selected tunnel (i.e. send a `SIGTERM`).
* `N`: Show the network connections related to each tunnel instances.
* `Q`: Quit Tunnelmon.
## DISPLAY
Tunnelmon displays a table where lines are [auto]ssh processes that sets up a tunnel.
Columns of the table indicates:
- TYPE: `auto` if the process is managed by autossh, `ssh` if it is a "raw" SSH tunnel;
- FORWARD: the type of port forwarding method (either `local`, `remote` or `dynamic`, see the SSH manual for details);
- SSHPID: the process identifier;
- INPORT: the client port;
- VIA: the client host;
- TARGET: the host address;
- OUTPORT: the host port.
The interactive interface adds a CONNECTIONS columns that displays one vertical bar for each connection set up by the tunnel.
If you ask for showing the connections list (typing `N` in the interactive interface, or not passing `-u` to the command line one),
Tunnelmon will show indented lines with the type of the connection, its status and the related address:port informations.
In the interactive interface, different colors are used for:
- the tunnel type,
- the port forwarding methods,
- privileged and unprivileged ports,
- loopback, private and regular addresses.
* `Q`: Quit tunnelmon.
## SSH Tunnels in a nutshell
@ -103,7 +72,6 @@ ssh -N host -L4567:server:1234
You may add `-f` to run ssh in the background.
Autossh can restart tunnels for you, in case they crash:
```
̏```
autossh -f host -L4567:server:1234
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Tunnelmon is an AutoSSH tunnel monitor
# Ereshkigal is an AutoSSH tunnel monitor
# It gives a curses user interface to monitor existing SSH tunnel that are managed with autossh.
#
# This program is free software: you can redistribute it and/or modify
@ -36,10 +36,9 @@ import re
import collections
import itertools
log_sensitive = False
class Tunnel:
def __init__(self, ssh_pid=None, in_port=None, via_host=None, target_host=None, out_port=None, forward=None):
def __init__(self, ssh_pid=None, in_port=None, via_host=None, target_host=None, out_port=None):
# assert ssh_pid is not None
self.ssh_pid = ssh_pid
assert in_port is not None
@ -50,18 +49,11 @@ class Tunnel:
self.target_host = target_host
assert out_port is not None
self.out_port = out_port
assert forward is not None
self.forwards = {'L':'local', 'R':'remote', 'D': 'dynamic'}
if forward in self.forwards:
self.forward = self.forwards[forward]
else:
self.forward = "unknown"
self.connections = []
def repr_tunnel(self):
return "%s\t%i\t%i\t%s\t%s\t%i" % (
self.forward,
return "%i\t%i\t%s\t%s\t%i" % (
self.ssh_pid,
self.in_port,
self.via_host,
@ -154,31 +146,25 @@ class TunnelsParser:
# only a list of connections OR autossh processes
# self.update()
self.re_forwarding = re.compile(r"-\w*([LRD])\w*\s*(\d+):(.*):(\d+)")
self.re_forwarding = re.compile(r"-L\s*(\d+):(.*):(\d+)")
self.header = 'TYPE\tFORWARD\tSSHPID\tINPORT\tVIA\tTARGET\tOUTPORT'
self.header = 'TYPE\tSSH_PID\tIN_PORT\tVIA_HOST\tTARGET_HOST\tOUT_PORT'
def get_tunnel(self, pos):
pid = list(self.tunnels.keys())[pos]
return self.tunnels[pid]
def parse(self, cmd):
try:
cmdline = " ".join(cmd)
except TypeError:
cmdline = cmd
cmdline = " ".join(cmd)
if log_sensitive:
logging.debug("[SENSITIVE] autossh cmd line: %s", cmdline)
logging.debug("forwarding regexp: %s" % self.re_forwarding)
logging.debug('autossh cmd line: %s', cmdline)
logging.debug('forwarding regexp: %s', self.re_forwarding)
match = self.re_forwarding.findall(cmdline)
if log_sensitive:
logging.debug("[SENSITIVE] match: %s", match)
logging.debug(match)
if match:
assert len(match) == 1
forward, in_port, target_host, out_port = match[0]
if log_sensitive:
logging.debug("[SENSITIVE] matches: %s", match)
in_port, target_host, out_port = match[0]
logging.debug("matches: %s", match)
else:
raise ValueError("is not a ssh tunnel")
@ -188,8 +174,7 @@ class TunnelsParser:
# FIXME this is an ugly hack
i = 1
while i < len(cmd):
if log_sensitive:
logging.debug("[SENSITIVE] here: %i %s", i, cmd[i])
logging.debug("ici: %i %s", i, cmd[i])
if cmd[i][0] == '-':
if cmd[i][1] in '46AaCfGgKkMNnqsTtVvXxYy':
# flag without argument
@ -203,7 +188,7 @@ class TunnelsParser:
via_host = cmd[i]
break
return int(in_port), via_host, target_host, int(out_port), forward
return int(in_port), via_host, target_host, int(out_port)
def update(self):
"""Gather and parse informations from the operating system"""
@ -219,41 +204,36 @@ class TunnelsParser:
pass
else:
if process['name'] == 'ssh':
if log_sensitive:
logging.debug("[SENSITIVE] process: %s ", process)
logging.debug(process)
try:
in_port, via_host, target_host, out_port, forward = self.parse(cmd)
in_port, via_host, target_host, out_port = self.parse(cmd)
except ValueError:
continue
if log_sensitive:
logging.debug("[SENSITIVE] parsed: %s %s %s %s %s", in_port, via_host, target_host, out_port, forward)
logging.debug("%s %s %s %s", in_port, via_host, target_host, out_port)
# Check if this ssh tunnel is managed by autossh.
parent = psutil.Process(process['ppid'])
if parent.name() == 'autossh':
# Add an autossh tunnel.
pid = parent.pid # autossh pid
self.tunnels[pid] = AutoTunnel(pid, process['pid'], in_port, via_host, target_host, out_port, forward)
self.tunnels[pid] = AutoTunnel(pid, process['pid'], in_port, via_host, target_host, out_port)
else:
# Add a raw tunnel.
pid = process['pid']
self.tunnels[pid] = RawTunnel(pid, in_port, via_host, target_host, out_port, forward)
self.tunnels[pid] = RawTunnel(pid, in_port, via_host, target_host, out_port)
for c in process['connections']:
if log_sensitive:
logging.debug("[SENSITIVE] connection: %s", c)
logging.debug(c)
laddr, lport = c.laddr
if c.raddr:
raddr, rport = c.raddr
else:
raddr, rport = (None, None)
connection = Connection(laddr, lport, raddr, rport, c.status, c.family)
if log_sensitive:
logging.debug("[SENSITIVE] connection: %s", connection)
logging.debug(connection)
self.tunnels[pid].connections.append(connection)
if log_sensitive:
logging.debug("[SENSITIVE] %s", self.tunnels)
logging.debug(self.tunnels)
def __repr__(self):
reps = [self.header]
@ -271,9 +251,6 @@ class CursesMonitor:
"""Textual user interface to display up-to-date informations about current tunnels"""
def __init__(self, scr):
# hide cursor
curses.curs_set(0)
# curses screen
self.scr = scr
@ -294,74 +271,26 @@ class CursesMonitor:
self.ui_delay = 0.05 # seconds between two screen update
# colors
# 0:black, 1:red, 2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.
self.colors_tunnel = {
'kind_auto' : curses.COLOR_CYAN,
'kind_raw' : curses.COLOR_BLUE,
'ssh_pid' : curses.COLOR_WHITE,
'in_port' : curses.COLOR_YELLOW,
'out_port' : curses.COLOR_YELLOW,
'in_port_priv' : curses.COLOR_RED,
'out_port_priv' : curses.COLOR_RED,
'via_host' : curses.COLOR_GREEN,
'target_host' : curses.COLOR_GREEN,
'via_local' : curses.COLOR_BLUE,
'target_local' : curses.COLOR_BLUE,
'via_priv' : curses.COLOR_CYAN,
'target_priv' : curses.COLOR_CYAN,
'tunnels_nb' : curses.COLOR_RED,
'tunnels_nb_none': curses.COLOR_RED,
'forward_local' : curses.COLOR_BLUE,
'forward_remote' : curses.COLOR_CYAN,
'forward_dynamic': curses.COLOR_YELLOW,
'forward_unknown': curses.COLOR_WHITE,
}
self.colors_highlight = {
'kind_auto' : 9,
'kind_raw' : 9,
'ssh_pid' : 9,
'in_port' : 9,
'out_port' : 9,
'in_port_priv' : 9,
'out_port_priv' : 9,
'via_host' : 9,
'target_host' : 9,
'via_local' : 9,
'target_local' : 9,
'via_priv' : 9,
'target_priv' : 9,
'tunnels_nb' : 9,
'tunnels_nb_none': 9,
'forward_local' : 9,
'forward_remote' : 9,
'forward_dynamic': 9,
'forward_unknown': 9,
}
self.colors_connection = {
'ssh_pid' : curses.COLOR_WHITE,
'autossh_pid' : curses.COLOR_WHITE,
'status' : curses.COLOR_CYAN,
'status_out' : curses.COLOR_RED,
'local_address' : curses.COLOR_BLUE,
'foreign_address': curses.COLOR_GREEN,
'in_port' : curses.COLOR_YELLOW,
'out_port' : curses.COLOR_YELLOW,
'in_port_priv' : curses.COLOR_RED,
'out_port_priv' : curses.COLOR_RED,
}
# FIXME different colors for different types of tunnels (auto or raw)
self.colors_tunnel = {'kind_auto': 4, 'kind_raw': 5, 'ssh_pid': 0, 'in_port': 3,
'via_host': 2, 'target_host': 2, 'out_port': 3, 'tunnels_nb': 4, 'tunnels_nb_none': 1}
self.colors_highlight = {'kind_auto': 9, 'kind_raw': 9, 'ssh_pid': 9, 'in_port': 9,
'via_host': 9, 'target_host': 9, 'out_port': 9, 'tunnels_nb': 9, 'tunnels_nb_none': 9}
self.colors_connection = {'ssh_pid': 0, 'autossh_pid': 0, 'status': 4, 'status_out': 1,
'local_address': 2, 'in_port': 3, 'foreign_address': 2, 'out_port': 3}
self.header = ("TYPE", "FORWARD", "SSHPID", "INPORT", "VIA", "TARGET", "OUTPORT")
self.header = ("TYPE", "SSHPID", "INPORT", "VIA", "TARGET", "OUTPORT")
def do_Q(self):
"""Quit"""
logging.debug("Waited: %s", self.log_ticks)
logging.debug("Waited: %s" % self.log_ticks)
self.log_ticks = ""
logging.debug("Key pushed: Q")
return False
def do_R(self):
"""Reload autossh tunnel"""
logging.debug("Waited: %s", self.log_ticks)
logging.debug("Waited: %s" % self.log_ticks)
self.log_ticks = ""
logging.debug("Key pushed: R")
# if a pid is selected
@ -369,8 +298,7 @@ class CursesMonitor:
# send the SIGUSR1 signal
if type(self.tp.get_tunnel(self.cur_line)) == AutoTunnel:
# autossh performs a reload of existing tunnels that it manages
if log_sensitive:
logging.debug("[SENSITIVE] SIGUSR1 on PID: %i", self.cur_pid)
logging.debug("SIGUSR1 on PID: %i" % self.cur_pid)
os.kill(self.cur_pid, signal.SIGUSR1)
else:
logging.debug("Cannot reload a RAW tunnel")
@ -378,7 +306,7 @@ class CursesMonitor:
def do_C(self):
"""Close tunnel"""
logging.debug("Waited: %s", self.log_ticks)
logging.debug("Waited: %s" % self.log_ticks)
self.log_ticks = ""
logging.debug("Key pushed: C")
if self.cur_pid != -1:
@ -388,21 +316,17 @@ class CursesMonitor:
tunnel = self.tp.get_tunnel(self.cur_line)
if type(tunnel) == AutoTunnel:
if log_sensitive:
logging.debug("[SENSITIVE] SIGKILL on autossh PID: %i", self.cur_pid)
logging.debug("SIGKILL on autossh PID: %i" % self.cur_pid)
try:
os.kill(self.cur_pid, signal.SIGKILL)
except OSError:
if log_sensitive:
logging.error("[SENSITIVE] No such process: %i", self.cur_pid)
logging.error("No such process: %i" % self.cur_pid)
if log_sensitive:
logging.debug("[SENSITIVE] SIGKILL on ssh PID: %i", tunnel.ssh_pid)
logging.debug("SIGKILL on ssh PID: %i" % tunnel.ssh_pid)
try:
os.kill(tunnel.ssh_pid, signal.SIGKILL)
except OSError:
if log_sensitive:
logging.error("[SENSITIVE] No such process: %i", tunnel.ssh_pid)
logging.error("No such process: %i" % tunnel.ssh_pid)
self.cur_line -= 1
self.cur_pid = -1
# FIXME update cur_pid or get rid of it everywhere
@ -410,7 +334,7 @@ class CursesMonitor:
def do_N(self):
"""Show connections"""
logging.debug("Waited: %s", self.log_ticks)
logging.debug("Waited: %s" % self.log_ticks)
self.log_ticks = ""
logging.debug("Key pushed: N")
self.show_connections = not self.show_connections
@ -418,7 +342,7 @@ class CursesMonitor:
def do_258(self):
"""Move down"""
logging.debug("Waited: %s", self.log_ticks)
logging.debug("Waited: %s" % self.log_ticks)
self.log_ticks = ""
logging.debug("Key pushed: down")
# if not the end of the list
@ -433,7 +357,7 @@ class CursesMonitor:
def do_259(self):
"""Move up"""
logging.debug("Waited: %s", self.log_ticks)
logging.debug("Waited: %s" % self.log_ticks)
self.log_ticks = ""
logging.debug("Key pushed: up")
if self.cur_line > -1:
@ -472,11 +396,10 @@ class CursesMonitor:
state = "%s" % self.tp
if state != self.last_state:
logging.debug("Waited: %s", self.log_ticks)
logging.debug("Waited: %s" % self.log_ticks)
self.log_ticks = ""
logging.debug("----- Time of screen update: %s -----", time.time())
if log_sensitive:
logging.debug("[SENSITIVE] State of tunnels:\n%s", self.tp)
logging.debug("----- Time of screen update: %s -----" % time.time())
logging.debug("State of tunnels:\n%s" % self.tp)
self.last_state = state
else:
self.log_ticks += "."
@ -495,12 +418,12 @@ class CursesMonitor:
# Call the do_* handler.
fch = "do_%s" % ch.capitalize()
fkc = "do_%i" % kc
logging.debug("key func: %s / %s", fch, fkc)
logging.debug("key func: %s / %s" % (fch, fkc))
if fch in dir(self):
notquit = eval("self."+fch+"()")
elif fkc in dir(self):
notquit = eval("self."+fkc+"()")
logging.debug("notquit = %s", notquit)
logging.debug("notquit = %s" % notquit)
# update the display
self.display()
@ -511,15 +434,14 @@ class CursesMonitor:
# end of the loop
def format(self):
"""Prepare formating strings to pad with spaces up to the column header width."""
reps = [self.tp.tunnels[t].repr_tunnel() for t in self.tp.tunnels]
tuns = [t.split() for t in reps]
tuns.append(self.header)
cols = itertools.zip_longest(*tuns, fillvalue='')
widths = [max(len(s) for s in col) for col in cols]
logging.debug("Columns widths: %s", widths)
logging.debug(widths)
fmt = ['{{: <{}}}'.format(w) for w in widths]
logging.debug("Columns formats: %s", fmt)
logging.debug(fmt)
return fmt
def display(self):
@ -555,6 +477,8 @@ class CursesMonitor:
self.cur_pid = -1
# header line
# header_msg = "TYPE\tINPORT\tVIA \tTARGET \tOUTPORT"
# if os.geteuid() == 0:
header_msg = " ".join(self.format()).format(*self.header)
header_msg += " CONNECTIONS"
self.scr.addstr(header_msg, curses.color_pair(color))
@ -609,67 +533,24 @@ class CursesMonitor:
"""Add line corresponding to the line-th autossh process"""
self.scr.addstr('\n')
# Handle on the current tunnel object.
t = self.tp.get_tunnel(line)
# Highlight selected line.
colors = self.colors_tunnel
if self.cur_line == line:
colors = self.colors_highlight
# TYPE
if type(self.tp.get_tunnel(line)) == AutoTunnel:
# Format 'auto' using the 0th column format string and the related color..
self.scr.addstr(self.format()[0].format('auto'), curses.color_pair(colors['kind_auto']))
# Trailing space.
self.scr.addstr(' ', curses.color_pair(colors['kind_auto']))
else:
self.scr.addstr(self.format()[0].format('ssh'), curses.color_pair(colors['kind_raw']))
self.scr.addstr(' ', curses.color_pair(colors['kind_raw']))
# FORWARD
fwd = t.forward
self.scr.addstr(self.format()[1].format(fwd), curses.color_pair(colors['forward_'+fwd]))
self.scr.addstr(' ', curses.color_pair(colors['forward_'+fwd]))
# self.add_tunnel_info('ssh_pid', line)
self.add_tunnel_info('ssh_pid', line, 1)
self.add_tunnel_info('in_port', line, 2)
self.add_tunnel_info('via_host', line, 3)
self.add_tunnel_info('target_host', line, 4)
self.add_tunnel_info('out_port', line, 5)
# SSHPID
self.add_tunnel_info('ssh_pid' , line, 2)
# INPORT
if t.in_port <= 1024:
self.scr.addstr(self.format()[3].format(t.in_port), curses.color_pair(colors['in_port_priv']))
self.scr.addstr(' ', curses.color_pair(colors['in_port_priv']))
else:
self.add_tunnel_info('in_port' , line, 3)
# VIA
if any(re.match(p,t.via_host) for p in ["^127\..*", "::1", "localhost"]): # loopback
self.scr.addstr(self.format()[4].format(t.via_host), curses.color_pair(colors['via_local']))
self.scr.addstr(' ', curses.color_pair(colors['via_local']))
elif any(re.match(p,t.via_host) for p in ["^10\..*", "^172\.[123][0-9]*\..*", "^192\.0\.0\.[0-9]+", "^192\.168\..*", "64:ff9b:1:.*", "fc00::.*"]): # private network
self.scr.addstr(self.format()[4].format(t.via_host), curses.color_pair(colors['via_priv']))
self.scr.addstr(' ', curses.color_pair(colors['via_priv']))
else:
self.add_tunnel_info('via_host' , line, 4)
# TARGET
if any(re.match(p,t.target_host) for p in ["^127\..*", "::1", "localhost"]): # loopback
self.scr.addstr(self.format()[5].format(t.target_host), curses.color_pair(colors['target_local']))
self.scr.addstr(' ', curses.color_pair(colors['target_local']))
elif any(re.match(p,t.target_host) for p in ["^10\..*", "^172\.[123][0-9]*\..*", "^192\.0\.0\.[0-9]+", "^192\.168\..*", "64:ff9b:1:.*", "fc00::.*"]): # private network
self.scr.addstr(self.format()[5].format(t.target_host), curses.color_pair(colors['target_priv']))
self.scr.addstr(' ', curses.color_pair(colors['target_priv']))
else:
self.add_tunnel_info('target_host' , line, 5)
# OUTPORT
if t.out_port <= 1024:
self.scr.addstr(self.format()[6].format(t.out_port), curses.color_pair(colors['out_port_priv']))
self.scr.addstr(' ', curses.color_pair(colors['out_port_priv']))
else:
self.add_tunnel_info('out_port' , line, 6)
# CONNECTIONS
nb = len(self.tp.get_tunnel(line).connections)
if nb > 0:
# for each connection related to this process
@ -712,7 +593,7 @@ if __name__ == "__main__":
usage = """%prog [options]
A user interface to monitor existing SSH tunnel that are managed with autossh.
Called without options, Tunnelmon displays a list of tunnels on the standard output.
Called without options, ereshkigal displays a list of tunnels on the standard output.
Note: Users other than root will not see tunnels connections.
Version 0.3"""
parser = OptionParser(usage=usage)
@ -740,22 +621,18 @@ if __name__ == "__main__":
help="Log to this file, default to standard output. \
If you use the curses interface, you may want to set this to actually see logs.")
parser.add_option("-s", "--log-sensitive",
action="store_true", default=False,
help="Do log sensitive informations (like hostnames, IPs and PIDs).")
parser.add_option('-f', '--config-file', default=None, metavar='FILE',
help="Use this configuration file (default: '~/.tunnelmon.conf')")
help="Use this configuration file (default: '~/.ereshkigal.conf')")
(asked_for, args) = parser.parse_args()
logmsg = "----- Started Tunnelmon -----"
logmsg = "----- Started Ereshkigal -----"
if asked_for.log_file:
logfile = asked_for.log_file
logging.basicConfig(filename=logfile, level=LOG_LEVELS[asked_for.log_level])
logging.debug(logmsg)
logging.debug("Log in %s", logfile)
logging.debug("Log in %s" % logfile)
else:
if asked_for.curses:
logging.warning("It's a bad idea to log to stdout while in the curses interface.")
@ -763,11 +640,7 @@ if __name__ == "__main__":
logging.debug(logmsg)
logging.debug("Log to stdout")
logging.debug("Asked for: %s" % asked_for)
if asked_for.log_sensitive:
logging.debug("Asked for logging sensitive information.")
log_sensitive = True
logging.debug("Asked for: %s", asked_for)
# unfortunately, asked_for class has no __len__ method in python 2.4.3 (bug?)
# if len(asked_for) > 1:
@ -781,7 +654,7 @@ if __name__ == "__main__":
logging.error("'%s' contains no known configuration", asked_for.config_file)
else:
try:
config.read('~/.tunnelmon.conf')
config.read('~/.ereshkigal.conf')
except configparser.MissingSectionHeaderError:
logging.error("'%s' contains no known configuration", asked_for.config_file)
@ -837,8 +710,7 @@ if __name__ == "__main__":
tp = TunnelsParser()
tp.update()
# do not call update() but only get connections
if log_sensitive:
logging.debug("[SENSITIVE] UID: %i", os.geteuid())
logging.debug("UID: %i.", os.geteuid())
# if os.geteuid() == 0:
for t in tp.tunnels:
for c in tp.tunnels[t].connections:
@ -864,3 +736,12 @@ if __name__ == "__main__":
# call the default __repr__
print(tp)
#
# In Mesopotamian mythology, Ereshkigal (lit. "great lady under earth")
# was the goddess of Irkalla, the land of the dead or underworld.
#
# Thus, she knows a lot about tunnels...
#
# http://en.wikipedia.org/wiki/Ereshkigal
#