Solving conflicts with dependencies

This commit is contained in:
Carlos Ortigoza Dempster 2017-04-18 15:01:14 +02:00
commit e3d376b716
6 changed files with 60 additions and 54 deletions

View file

@ -12,7 +12,7 @@ OpenSnitch is a GNU/Linux port of the Little Snitch application firewall.
## Install
sudo apt-get install nfqueue-bindings-python
sudo apt-get install build-essential python-dev libnetfilter-queue-dev
cd opensnitch
sudo python setup.py install

View file

@ -32,25 +32,30 @@ class DNSCollector:
return False
def add_response( self, packet ):
with self.lock:
try:
a_count = packet[DNS].ancount
i = a_count + 4
while i > 4:
hostname = packet[0][i].rrname
address = packet[0][i].rdata
i -= 1
if packet.haslayer(DNS) and packet.haslayer(DNSRR):
with self.lock:
try:
a_count = packet[DNS].ancount
i = a_count + 4
while i > 4:
hostname = packet[0][i].rrname
address = packet[0][i].rdata
i -= 1
if hostname == '.':
continue
if hostname == '.':
continue
elif hostname.endswith('.'):
hostname = hostname[:-1]
elif hostname.endswith('.'):
hostname = hostname[:-1]
logging.debug( "Adding DNS response: %s => %s" % ( address, hostname ) )
self.hosts[address] = hostname
except Exception, e:
logging.exception("Error while parsing DNS response:")
# for CNAME records
if address.endswith('.'):
address = address[:-1]
logging.debug( "Adding DNS response: %s => %s" % ( address, hostname ) )
self.hosts[address] = hostname
except Exception, e:
logging.error("Error while parsing DNS response: %s" % e)
def get_hostname( self, address ):
with self.lock:

View file

@ -16,17 +16,19 @@
# program. If not, go to http://www.gnu.org/licenses/gpl.html
# or write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import nfqueue
import logging
from threading import Lock
class Rule:
ACCEPT = 0
DROP = 1
def __init__(self):
self.app_path = None
self.address = None
self.port = None
self.proto = None
self.verdict = nfqueue.NF_ACCEPT
self.verdict = Rule.ACCEPT
def matches( self, c ):
if self.app_path != c.app_path:
@ -61,7 +63,7 @@ class Rules:
def add_rule( self, connection, verdict, apply_to_all = False ):
with self.mutex:
logging.debug( "Adding %s rule for '%s' (all=%s)" % (
"ALLOW" if verdict == nfqueue.NF_ACCEPT else "DENY",
"ALLOW" if verdict == Rule.ACCEPT else "DENY",
connection,
"true" if apply_to_all == True else "false" ) )
r = Rule()

View file

@ -18,7 +18,7 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import os
import logging
import nfqueue
from netfilterqueue import NetfilterQueue
from socket import AF_INET, AF_INET6, inet_ntoa
from threading import Lock
from scapy.all import *
@ -26,7 +26,7 @@ from scapy.all import *
from opensnitch.ui import UI
from opensnitch.connection import Connection
from opensnitch.dns import DNSCollector
from opensnitch.rule import Rules
from opensnitch.rule import Rule, Rules
class Snitch:
IPTABLES_RULES = ( # Get DNS responses
@ -41,11 +41,9 @@ class Snitch:
self.lock = Lock()
self.rules = Rules()
self.dns = DNSCollector()
self.q = nfqueue.queue()
self.q = NetfilterQueue()
self.q.set_callback( self.pkt_callback )
self.q.fast_open(0, AF_INET)
self.q.set_queue_maxlen(2*1024)
self.q.bind( 0, self.pkt_callback, 1024 * 2 )
def get_verdict(self,c):
verdict = self.rules.get_verdict(c)
@ -53,16 +51,17 @@ class Snitch:
if verdict is None:
with self.lock:
c.hostname = self.dns.get_hostname(c.dst_addr)
( verdict, apply_for_all ) = UI.prompt_user(c)
self.rules.add_rule( c, verdict, apply_for_all )
( save, verdict, apply_for_all ) = UI.prompt_user(c)
if save:
self.rules.add_rule( c, verdict, apply_for_all )
return verdict
def pkt_callback(self,pkt):
verd = nfqueue.NF_ACCEPT
verd = Rule.ACCEPT
try:
data = pkt.get_data()
data = pkt.get_payload()
packet = IP(data)
if self.dns.is_dns_response(packet):
@ -82,26 +81,24 @@ class Snitch:
except Exception, e:
logging.exception( "Exception on packet callback:" )
if verd == nfqueue.NF_DROP:
if verd == Rule.DROP:
logging.info( "Dropping %s from %s" % ( conn, conn.get_app_name() ) )
# mark this packet so iptables will drop it
pkt.set_verdict_mark( verd, 1 )
pkt.set_mark(1)
pkt.drop()
else:
pkt.set_verdict(verd)
return 1
pkt.accept()
def start(self):
for r in Snitch.IPTABLES_RULES:
logging.debug( "Applying iptables rule '%s'" % r )
os.system( "iptables -I %s" % r )
self.q.try_run()
self.q.run()
def stop(self):
for r in Snitch.IPTABLES_RULES:
logging.debug( "Deleting iptables rule '%s'" % r )
os.system( "iptables -D %s" % r )
self.q.unbind(AF_INET)
self.q.close()
self.q.unbind()

View file

@ -17,12 +17,26 @@
# or write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import easygui as g
import nfqueue
from opensnitch.rule import Rule
# TODO: Implement a better UI.
# TODO: Implement tray icon and menu.
# TODO: Implement rules editor.
class UI:
CHOICES = [ 'Allow Once',
'Allow All',
'Deny Once',
'Deny All' ]
RESULTS = [ \
# save | verdict | all
( False, Rule.ACCEPT, False ),
( True, Rule.ACCEPT, True ),
( False, Rule.DROP, False ),
( True, Rule.DROP, True )
]
@staticmethod
def prompt_user( c ):
title = 'OpenSnitch'
@ -33,19 +47,7 @@ class UI:
c.proto.upper(),
c.dst_port,
" (%s)" % c.service if c.service is not None else '' )
choices = [ 'Allow Once',
'Allow All',
'Deny Once',
'Deny All' ]
idx = g.indexbox(msg, title, choices)
results = [ \
( nfqueue.NF_ACCEPT, False ),
( nfqueue.NF_ACCEPT, True ),
( nfqueue.NF_DROP, False ),
( nfqueue.NF_DROP, True )
]
return results[idx]
idx = g.indexbox( msg, title, UI.CHOICES )
return UI.RESULTS[idx]

View file

@ -36,5 +36,5 @@ setup( name = 'opensnitch',
scripts = [ 'bin/opensnitch' ],
license = 'GPL',
zip_safe = False,
install_requires = [ 'scapy', 'easygui', 'dpkt', 'psutil' ]
install_requires = [ 'scapy', 'easygui', 'dpkt', 'NetfilterQueue', 'psutil' ]
)