def test_not_listening(self, mock_get_utility, mock_process, mock_net): from psutil._common import sconn conns = [ sconn(fd=-1, family=2, type=1, laddr=("0.0.0.0", 30), raddr=(), status="LISTEN", pid=None), sconn(fd=3, family=2, type=1, laddr=("192.168.5.10", 32783), raddr=("20.40.60.80", 22), status="ESTABLISHED", pid=1234), sconn(fd=-1, family=10, type=1, laddr=("::1", 54321), raddr=("::1", 111), status="CLOSE_WAIT", pid=None) ] mock_net.return_value = conns mock_process.name.return_value = "inetd" self.assertFalse(self._call(17)) self.assertEqual(mock_get_utility.generic_notification.call_count, 0) self.assertEqual(mock_process.call_count, 0)
def test_race_condition(self, mock_get_utility, mock_process, mock_net): # This tests a race condition, or permission problem, or OS # incompatibility in which, for some reason, no process name can be # found to match the identified listening PID. from psutil._common import sconn conns = [ sconn(fd=-1, family=2, type=1, laddr=("0.0.0.0", 30), raddr=(), status="LISTEN", pid=None), sconn( fd=3, family=2, type=1, laddr=("192.168.5.10", 32783), raddr=("20.40.60.80", 22), status="ESTABLISHED", pid=1234, ), sconn(fd=-1, family=10, type=1, laddr=("::1", 54321), raddr=("::1", 111), status="CLOSE_WAIT", pid=None), sconn(fd=3, family=2, type=1, laddr=("0.0.0.0", 17), raddr=(), status="LISTEN", pid=4416), ] mock_net.return_value = conns mock_process.side_effect = psutil.NoSuchProcess("No such PID") # We simulate being unable to find the process name of PID 4416, # which results in returning False. self.assertFalse(self.authenticator.already_listening(17)) self.assertEqual(mock_get_utility.generic_notification.call_count, 0) mock_process.assert_called_once_with(4416)
def test_not_listening(self, mock_get_utility, mock_process, mock_net): from psutil._common import sconn conns = [ sconn(fd=-1, family=2, type=1, laddr=('0.0.0.0', 30), raddr=(), status='LISTEN', pid=None), sconn(fd=3, family=2, type=1, laddr=('192.168.5.10', 32783), raddr=('20.40.60.80', 22), status='ESTABLISHED', pid=1234), sconn(fd=-1, family=10, type=1, laddr=('::1', 54321), raddr=('::1', 111), status='CLOSE_WAIT', pid=None)] mock_net.return_value = conns mock_process.name.return_value = "inetd" self.assertFalse(self.authenticator.already_listening(17)) self.assertEqual(mock_get_utility.generic_notification.call_count, 0) self.assertEqual(mock_process.call_count, 0)
def test_not_listening(self, mock_get_utility, mock_process, mock_net): from psutil._common import sconn conns = [ sconn(fd=-1, family=2, type=1, laddr=("0.0.0.0", 30), raddr=(), status="LISTEN", pid=None), sconn(fd=3, family=2, type=1, laddr=("192.168.5.10", 32783), raddr=("20.40.60.80", 22), status="ESTABLISHED", pid=1234), sconn(fd=-1, family=10, type=1, laddr=("::1", 54321), raddr=("::1", 111), status="CLOSE_WAIT", pid=None)] mock_net.return_value = conns mock_process.name.return_value = "inetd" self.assertFalse(self.authenticator.already_listening(17)) self.assertEqual(mock_get_utility.generic_notification.call_count, 0) self.assertEqual(mock_process.call_count, 0)
def test_get_connections_from_sockets_should_return_connections_by_type_when_ok( self, mocked_net_connections): unix_conns = [ sconn(fd=6, family=1, type=1, laddr='/var/run/postgres/.s.PGSQL.5432', raddr=None, status='NONE', pid=1048), ] tcp_conns = [ sconn(fd=6, family=1, type=1, laddr=('127.0.0.1', 5432), raddr=None, status='NONE', pid=1048), sconn(fd=6, family=1, type=1, laddr=('127.0.0.1', 5432), raddr=None, status='NONE', pid=1049) ] tcp6_conns = [ sconn(fd=6, family=1, type=1, laddr=('127.0.0.1', 5432), raddr=None, status='NONE', pid=1048), ] mocked_net_connections.side_effect = [ unix_conns, tcp_conns, tcp6_conns ] parser = ProcNetParser(1048) expected_connections = { 'unix': [('/var/run/postgres', '5432')], 'tcp6': [('127.0.0.1', 5432)], 'tcp': [('127.0.0.1', 5432)] } self.assertEqual(expected_connections, parser.get_connections_from_sockets())
def test_check_ports(m_utils, m_sh, mocker): m_net_connections = mocker.patch(TESTED + '.psutil.net_connections', autospec=True) m_net_connections.return_value = [] m_utils.getenv.side_effect = lambda k, default: default actions.check_ports() m_utils.path_exists.return_value = False actions.check_ports() # Find a mapped port m_net_connections.return_value = [ _common.sconn(fd=0, family=AF_INET6, type=SOCK_STREAM, laddr=_common.addr('::', 1234), raddr=('::', 44444), status='ESTABLISHED', pid=None), _common.sconn(fd=0, family=AF_INET, type=SOCK_STREAM, laddr=_common.addr('0.0.0.0', 80), raddr=_common.addr('::', 44444), status='ESTABLISHED', pid=None), _common.sconn(fd=0, family=AF_INET6, type=SOCK_STREAM, laddr=_common.addr('::', 80), raddr=_common.addr('::', 44444), status='ESTABLISHED', pid=None), ] actions.check_ports() m_utils.confirm.return_value = False with pytest.raises(SystemExit): actions.check_ports() # no mapped ports found -> no need for confirm m_net_connections.return_value = [] actions.check_ports() # warn and continue on error m_net_connections.side_effect = AccessDenied actions.check_ports()
def net_connections(kind, _pid=-1): """Return socket connections. If pid == -1 return system-wide connections (as opposed to connections opened by one process only). Only INET sockets are returned (UNIX are not). """ cmap = _common.conn_tmap.copy() if _pid == -1: cmap.pop('unix', 0) if kind not in cmap: raise ValueError("invalid %r kind argument; choose between %s" % (kind, ', '.join([repr(x) for x in cmap]))) families, types = _common.conn_tmap[kind] rawlist = cext.net_connections(_pid, families, types) ret = [] for item in rawlist: fd, fam, type_, laddr, raddr, status, pid = item if fam not in families: continue if type_ not in types: continue status = TCP_STATUSES[status] if _pid == -1: nt = _common.sconn(fd, fam, type_, laddr, raddr, status, pid) else: nt = _common.pconn(fd, fam, type_, laddr, raddr, status) ret.append(nt) return ret
def retrieve(self, kind, pid=None): if kind not in self.tmap: raise ValueError("invalid %r kind argument; choose between %s" % (kind, ', '.join([repr(x) for x in self.tmap]))) if pid is not None: inodes = self.get_proc_inodes(pid) if not inodes: # no connections for this process return [] else: inodes = self.get_all_inodes() ret = [] for f, family, type_ in self.tmap[kind]: if family in (socket.AF_INET, socket.AF_INET6): ls = self.process_inet("/proc/net/%s" % f, family, type_, inodes, filter_pid=pid) else: ls = self.process_unix("/proc/net/%s" % f, family, inodes, filter_pid=pid) for fd, family, type_, laddr, raddr, status, bound_pid in ls: if pid: conn = _common.pconn(fd, family, type_, laddr, raddr, status) else: conn = _common.sconn(fd, family, type_, laddr, raddr, status, bound_pid) ret.append(conn) return ret
def retrieve(self, kind, pid=None): if kind not in self.tmap: raise ValueError("invalid %r kind argument; choose between %s" % (kind, ', '.join([repr(x) for x in self.tmap]))) if pid is not None: inodes = self.get_proc_inodes(pid) if not inodes: # no connections for this process return [] else: inodes = self.get_all_inodes() ret = [] for f, family, type_ in self.tmap[kind]: if family in (socket.AF_INET, socket.AF_INET6): ls = self.process_inet( "/proc/net/%s" % f, family, type_, inodes, filter_pid=pid) else: ls = self.process_unix( "/proc/net/%s" % f, family, inodes, filter_pid=pid) for fd, family, type_, laddr, raddr, status, bound_pid in ls: if pid: conn = _common.pconn(fd, family, type_, laddr, raddr, status) else: conn = _common.sconn(fd, family, type_, laddr, raddr, status, bound_pid) ret.append(conn) return ret
def test_listening_ipv4(self, mock_get_utility, mock_process, mock_net): from psutil._common import sconn conns = [ sconn(fd=-1, family=2, type=1, laddr=('0.0.0.0', 30), raddr=(), status='LISTEN', pid=None), sconn(fd=3, family=2, type=1, laddr=('192.168.5.10', 32783), raddr=('20.40.60.80', 22), status='ESTABLISHED', pid=1234), sconn(fd=-1, family=10, type=1, laddr=('::1', 54321), raddr=('::1', 111), status='CLOSE_WAIT', pid=None), sconn(fd=3, family=2, type=1, laddr=('0.0.0.0', 17), raddr=(), status='LISTEN', pid=4416)] mock_net.return_value = conns mock_process.name.return_value = "inetd" result = self.authenticator.already_listening(17) self.assertTrue(result) self.assertEqual(mock_get_utility.call_count, 1) mock_process.assert_called_once_with(4416)
def test_listening_ipv4(self, mock_get_utility, mock_process, mock_net): from psutil._common import sconn conns = [ sconn(fd=-1, family=2, type=1, laddr=("0.0.0.0", 30), raddr=(), status="LISTEN", pid=None), sconn(fd=3, family=2, type=1, laddr=("192.168.5.10", 32783), raddr=("20.40.60.80", 22), status="ESTABLISHED", pid=1234), sconn(fd=-1, family=10, type=1, laddr=("::1", 54321), raddr=("::1", 111), status="CLOSE_WAIT", pid=None), sconn(fd=3, family=2, type=1, laddr=("0.0.0.0", 17), raddr=(), status="LISTEN", pid=4416)] mock_net.return_value = conns mock_process.name.return_value = "inetd" result = self._call(17, True) self.assertTrue(result) self.assertEqual(mock_get_utility.call_count, 1) mock_process.assert_called_once_with(4416)
def test_listening_ipv4(self, mock_get_utility, mock_process, mock_net): from psutil._common import sconn conns = [ sconn(fd=-1, family=2, type=1, laddr=("0.0.0.0", 30), raddr=(), status="LISTEN", pid=None), sconn(fd=3, family=2, type=1, laddr=("192.168.5.10", 32783), raddr=("20.40.60.80", 22), status="ESTABLISHED", pid=1234), sconn(fd=-1, family=10, type=1, laddr=("::1", 54321), raddr=("::1", 111), status="CLOSE_WAIT", pid=None), sconn(fd=3, family=2, type=1, laddr=("0.0.0.0", 17), raddr=(), status="LISTEN", pid=4416)] mock_net.return_value = conns mock_process.name.return_value = "inetd" result = self.authenticator.already_listening(17) self.assertTrue(result) self.assertEqual(mock_get_utility.call_count, 1) mock_process.assert_called_once_with(4416)
def test_get_socket_connections_exclude_by_pid(self, mocked_net_connections): unix_conns = [ sconn(fd=6, family=1, type=1, laddr='/var/run/postgres/.s.PGSQL.5432', raddr=None, status='NONE', pid=1048), sconn(fd=6, family=1, type=1, laddr='/var/run/postgres/.s.PGSQL.5432', raddr=None, status='NONE', pid=1049) ] tcp_conns = [ sconn(fd=6, family=1, type=1, laddr=('127.0.0.1', 5432), raddr=None, status='NONE', pid=1048), sconn(fd=6, family=1, type=1, laddr=('127.0.0.1', 5432), raddr=None, status='NONE', pid=1049) ] mocked_net_connections.side_effect = [unix_conns, tcp_conns, []] parser = ProcNetParser(1048) self.assertEqual(1, len(parser.sockets['unix'])) self.assertIn(unix_conns[0], parser.sockets['unix']) self.assertEqual(1, len(parser.sockets['tcp'])) self.assertIn(tcp_conns[0], parser.sockets['tcp'])
def test_race_condition(self, mock_get_utility, mock_process, mock_net): # This tests a race condition, or permission problem, or OS # incompatibility in which, for some reason, no process name can be # found to match the identified listening PID. import psutil from psutil._common import sconn conns = [ sconn(fd=-1, family=2, type=1, laddr=("0.0.0.0", 30), raddr=(), status="LISTEN", pid=None), sconn(fd=3, family=2, type=1, laddr=("192.168.5.10", 32783), raddr=("20.40.60.80", 22), status="ESTABLISHED", pid=1234), sconn(fd=-1, family=10, type=1, laddr=("::1", 54321), raddr=("::1", 111), status="CLOSE_WAIT", pid=None), sconn(fd=3, family=2, type=1, laddr=("0.0.0.0", 17), raddr=(), status="LISTEN", pid=4416) ] mock_net.return_value = conns mock_process.side_effect = psutil.NoSuchProcess("No such PID") # We simulate being unable to find the process name of PID 4416, # which results in returning False. self.assertFalse(self._call(17)) self.assertEqual(mock_get_utility.generic_notification.call_count, 0) mock_process.assert_called_once_with(4416)
def test__get_connection_by_type_should_return_conn_params_when_unix_type_ok( self, mocked_net_connections): parser = ProcNetParser(1048) unix_conn = sconn(fd=6, family=1, type=1, laddr='/var/run/postgres/.s.PGSQL.5432', raddr=None, status='NONE', pid=1048) conn_params = parser._get_connection_by_type('unix', unix_conn) self.assertEqual(('/var/run/postgres', '5432'), conn_params)
def test_measure_calls_psutil_net_connections(self, mock_net_connections): from psutil._common import sconn, addr from socket import AddressFamily, SocketKind conn1 = { "fd": 34, "family": AddressFamily(7), "type": SocketKind(2), "laddr": addr(ip='192.168.0.11', port=55878), "raddr": (), "status": "ESTABLISHED", "pid": 345, } conn2 = { "fd": 5, "family": AddressFamily(4), "type": SocketKind(1), "laddr": addr(ip='192.168.0.40', port=5802), "raddr": addr(ip='127.0.0.2', port=3123), "status": "NONE", "pid": 3336, } out_conn1 = conn1.copy() out_conn2 = conn2.copy() for out_conn in out_conn1, out_conn2: out_conn["family"] = repr(out_conn["family"]) out_conn["type"] = repr(out_conn["type"]) out_conn["laddr"] = dict(out_conn["laddr"]._asdict()) try: out_conn["raddr"] = dict(out_conn["raddr"]._asdict()) except AttributeError: pass conns = [sconn(**conn1), sconn(**conn2)] mock_net_connections.return_value = conns expected = [out_conn1, out_conn2] result = self.instance.measure() mock_net_connections.assert_called_once_with() self.assertEqual(result, expected)
def net_connections(kind='inet'): # Note: on OSX this will fail with AccessDenied unless # the process is owned by root. ret = [] for pid in pids(): try: cons = Process(pid).connections(kind) except NoSuchProcess: continue else: if cons: for c in cons: c = list(c) + [pid] ret.append(_common.sconn(*c)) return ret
def net_connections(kind): if kind not in _common.conn_tmap: raise ValueError("invalid %r kind argument; choose between %s" % (kind, ', '.join([repr(x) for x in conn_tmap]))) families, types = conn_tmap[kind] ret = [] rawlist = cext.net_connections() for item in rawlist: fd, fam, type, laddr, raddr, status, pid = item # TODO: apply filter at C level if fam in families and type in types: status = TCP_STATUSES[status] nt = _common.sconn(fd, fam, type, laddr, raddr, status, pid) ret.append(nt) return ret
def test__get_connection_by_type_should_return_none_when_unix_type_wrong_format( self, mocked_net_connections, mocked_logger): parser = ProcNetParser(1048) unix_conn = sconn(fd=6, family=1, type=1, laddr='/var/run/.s.PGSQQL.5432', raddr=None, status='NONE', pid=1048) conn_params = parser._get_connection_by_type('unix', unix_conn) self.assertIsNone(conn_params) expected_msg = 'unix socket name is not recognized as belonging to PostgreSQL: {0}'.format( unix_conn) mocked_logger.warning.assert_called_with(expected_msg)
def test__get_connection_by_type_should_return_conn_params_when_tcp_type_ok( self, mocked_net_connections): parser = ProcNetParser(1048) unix_conn = sconn(fd=3, family=2, type=1, laddr=('127.0.0.1', 5432), raddr=(), status='LISTEN', pid=1048) conn_params = parser._get_connection_by_type('tcp', unix_conn) self.assertEqual(('127.0.0.1', 5432), conn_params) conn_params = parser._get_connection_by_type('tcp6', unix_conn) self.assertEqual(('127.0.0.1', 5432), conn_params)
def net_connections(kind, _pid=-1): """Return socket connections. If pid == -1 return system-wide connections (as opposed to connections opened by one process only). """ if kind not in conn_tmap: raise ValueError("invalid %r kind argument; choose between %s" % (kind, ', '.join([repr(x) for x in conn_tmap]))) families, types = conn_tmap[kind] rawlist = cext.net_connections(_pid, families, types) ret = [] for item in rawlist: fd, fam, type, laddr, raddr, status, pid = item status = TCP_STATUSES[status] if _pid == -1: nt = _common.sconn(fd, fam, type, laddr, raddr, status, pid) else: nt = _common.pconn(fd, fam, type, laddr, raddr, status) ret.append(nt) return ret