Re: [apparmor] [patch 1/3] Add NetworkRule and NetworkRuleset classes

2015-04-19 Thread Kshitij Gupta
Hello,

On Sat, Apr 18, 2015 at 2:49 AM, Christian Boltz  wrote:

> Hello,
>
> Am Mittwoch, 15. April 2015 schrieb Kshitij Gupta:
> > On Wed, Apr 15, 2015 at 3:07 AM, Christian Boltz wrote:
> > > this patch adds utils/apparmor/rule/network.py with the NetworkRule
> > > and NetworkRuleset classes. These classes are meant to handle
> > > network rules.
> > >
> > > In comparison to the existing code in aa.py, relevant news are:
> > > - the keywords are checked against a list of allowed domains, types
> > > and>
> > >   protocols (these lists are based on what the utils/vim/Makefile
> > >   generates - on the long term an autogenerated file with the
> > >   keywords
> > >   for all rule types would be nice ;-)
> >
> > In theory you can have a script generate a python module that solely
> > contains these keywords, which can be imported in here. Sounds pretty
> > trivial ;-)
>
> We have something like that already for creating apparmor.vim (see
> utils/vim/Makefile) - but I'd describe the code that does that as
> "scary" ;-)
>
> Yes, it can be done, and it can even be done in a more sane way ;-)
>
> > > - there are variables for domain and type_or_protocol instead of
> > >
> > >   first_param and second_param. (If someone is bored enough to map
> > >   the
> > >   protocol "shortcuts" to their expanded meaning, that shouldn't be
> > >   too
> > >   hard.)
> > >
> > > - (obviously) more readable code because we have everything at one
> > > place>
> > >   now
> >
> > yay!
> >
> > > - some bugs are fixed along the way (for example, "network foo" will
> > > now>
> > >   be kept, not "network foo bar" - see my last mail about
> > >   write_net_rules() for details)
> > >
> > > [ 44-add-NetworkRule-and-NetworkRuleset-classes.diff ]
> > >
> > > === added file 'utils/apparmor/rule/network.py'
> > > --- utils/apparmor/rule/network.py  1970-01-01 00:00:00 +
> > > +++ utils/apparmor/rule/network.py  2015-04-14 20:47:40 +
>
> > > +# missing in manpage: 'unix', 'rds', 'llc', 'can', 'tipc',
> > > 'iucv', 'rxrpc', 'isdn', 'phonet', 'ieee802154', 'caif', 'alg',
> > > 'nfc', 'vsock'
> > > +
> >
> > comments from others on the missing types?
>
> That line should have gone into a bugreport or a patch for
> parser/apparmor.d.pod ;-)
>
> > > +network_type_keywords = ['stream', 'dgram', 'seqpacket', 'rdm',
> > 'raw',
> > > 'packet']
> > > +network_protocol_keywords = ['tcp', 'udp', 'icmp']
> > > +
> > > +
> > > +RE_NETWORK_DOMAIN   = '(' + '|'.join(network_domain_keywords) + ')'
> > > +RE_NETWORK_TYPE = '(' + '|'.join(network_type_keywords) + ')'
> > > +RE_NETWORK_PROTOCOL = '(' + '|'.join(network_protocol_keywords) +
> > > ')'
> > neat!
>
> If we need it more often, it might even be worth a little function.
> We'll see...
>
> > > +RE_NETWORK_DETAILS  = re.compile(
> > > +'^\s*(' +
> > > +'(?P' + RE_NETWORK_DOMAIN +
> > > ')(\s+(?P' + RE_NETWORK_TYPE + '|' +
> > > RE_NETWORK_PROTOCOL + '))?' + # domain, optional type or protocol
> >
> > exercising new/larger monitor privileges?  ;-)
>
> Not really, it even fits on my laptop screen ;-)
>
> > can be split into two lines I think.
>
> Good idea.
>
> > +'|' + # or
> >
> > > +'(?P' + RE_NETWORK_PROTOCOL + ')' + # protocol
> > > only +')\s*$')
> >
> > The leading and trailing \s* become superfluous as __parse has:
> > rule_details = matches.group('details').strip()
>
> I know, but it doesn't hurt and helps in case someone uses that regex
> in another way one day ;-)
>
> > > +
> > > +
> > > +
> > > +
> > > +
> >
> > what is the standard for whitespace separation?
>
> I don't know if there's a standard ;-)
>
> > 7 seems a bit much.
>
> Agreed, I trimmed some of them.
>
> > > +else:
> > > +raise AppArmorBug('Passed unknown domain to
> > > NetworkRule: %s' % str(domain))
> >
> > str(domain) is unnecessary, as type of domain is known to be str.
>
> Indeed, it's superfluous inside an "elif type(domain) == str:" ;-)
>
> > > +else:
> > > +raise AppArmorBug('Passed unknown object to
> > > NetworkRule: %s' % str(domain))
>
> (but still needed here)
>
> > > +self.type_or_protocol = None
> > > +self.all_type_or_protocols = False
> > > +if type_or_protocol == NetworkRule.ALL:
> > > +self.all_type_or_protocols = True
> > > +elif type(type_or_protocol) == str:
> > > +if type_or_protocol in network_protocol_keywords:
> > > +self.type_or_protocol = type_or_protocol
> > > +elif type_or_protocol in network_type_keywords:
> > > +if self.all_domains:
> > > +raise AppArmorException('Passing type %s to
> > > NetworkRule without specifying a domain keyword is not allowed' %
> > > str(type_or_protocol))
> >
> > str(type_or_protocol) not required.
>
> Right.
>
> > +self.type_or_protocol = type_or_protocol
> >
> > > +else:
> > > +raise AppArmorBu

Re: [apparmor] [patch 1/3] Add NetworkRule and NetworkRuleset classes

2015-04-17 Thread Christian Boltz
Hello,

Am Mittwoch, 15. April 2015 schrieb Kshitij Gupta:
> On Wed, Apr 15, 2015 at 3:07 AM, Christian Boltz wrote:
> > this patch adds utils/apparmor/rule/network.py with the NetworkRule
> > and NetworkRuleset classes. These classes are meant to handle
> > network rules.
> > 
> > In comparison to the existing code in aa.py, relevant news are:
> > - the keywords are checked against a list of allowed domains, types
> > and> 
> >   protocols (these lists are based on what the utils/vim/Makefile
> >   generates - on the long term an autogenerated file with the
> >   keywords
> >   for all rule types would be nice ;-)
> 
> In theory you can have a script generate a python module that solely
> contains these keywords, which can be imported in here. Sounds pretty
> trivial ;-)

We have something like that already for creating apparmor.vim (see 
utils/vim/Makefile) - but I'd describe the code that does that as 
"scary" ;-)

Yes, it can be done, and it can even be done in a more sane way ;-)

> > - there are variables for domain and type_or_protocol instead of
> > 
> >   first_param and second_param. (If someone is bored enough to map
> >   the
> >   protocol "shortcuts" to their expanded meaning, that shouldn't be
> >   too
> >   hard.)
> > 
> > - (obviously) more readable code because we have everything at one
> > place> 
> >   now
> 
> yay!
> 
> > - some bugs are fixed along the way (for example, "network foo" will
> > now> 
> >   be kept, not "network foo bar" - see my last mail about
> >   write_net_rules() for details)
> > 
> > [ 44-add-NetworkRule-and-NetworkRuleset-classes.diff ]
> > 
> > === added file 'utils/apparmor/rule/network.py'
> > --- utils/apparmor/rule/network.py  1970-01-01 00:00:00 +
> > +++ utils/apparmor/rule/network.py  2015-04-14 20:47:40 +

> > +# missing in manpage: 'unix', 'rds', 'llc', 'can', 'tipc',
> > 'iucv', 'rxrpc', 'isdn', 'phonet', 'ieee802154', 'caif', 'alg',
> > 'nfc', 'vsock'
> > +
> 
> comments from others on the missing types?

That line should have gone into a bugreport or a patch for
parser/apparmor.d.pod ;-)

> > +network_type_keywords = ['stream', 'dgram', 'seqpacket', 'rdm',
> 'raw',
> > 'packet']
> > +network_protocol_keywords = ['tcp', 'udp', 'icmp']
> > +
> > +
> > +RE_NETWORK_DOMAIN   = '(' + '|'.join(network_domain_keywords) + ')'
> > +RE_NETWORK_TYPE = '(' + '|'.join(network_type_keywords) + ')'
> > +RE_NETWORK_PROTOCOL = '(' + '|'.join(network_protocol_keywords) +
> > ')'
> neat!

If we need it more often, it might even be worth a little function. 
We'll see...

> > +RE_NETWORK_DETAILS  = re.compile(
> > +'^\s*(' +
> > +'(?P' + RE_NETWORK_DOMAIN +
> > ')(\s+(?P' + RE_NETWORK_TYPE + '|' +
> > RE_NETWORK_PROTOCOL + '))?' + # domain, optional type or protocol
> 
> exercising new/larger monitor privileges?  ;-)

Not really, it even fits on my laptop screen ;-)

> can be split into two lines I think.

Good idea.

> +'|' + # or
> 
> > +'(?P' + RE_NETWORK_PROTOCOL + ')' + # protocol
> > only +')\s*$')
> 
> The leading and trailing \s* become superfluous as __parse has:
> rule_details = matches.group('details').strip()

I know, but it doesn't hurt and helps in case someone uses that regex
in another way one day ;-)

> > +
> > +
> > +
> > +
> > +
> 
> what is the standard for whitespace separation? 

I don't know if there's a standard ;-)

> 7 seems a bit much.

Agreed, I trimmed some of them.
 
> > +else:
> > +raise AppArmorBug('Passed unknown domain to
> > NetworkRule: %s' % str(domain))
> 
> str(domain) is unnecessary, as type of domain is known to be str.

Indeed, it's superfluous inside an "elif type(domain) == str:" ;-)
 
> > +else:
> > +raise AppArmorBug('Passed unknown object to
> > NetworkRule: %s' % str(domain))

(but still needed here)

> > +self.type_or_protocol = None
> > +self.all_type_or_protocols = False
> > +if type_or_protocol == NetworkRule.ALL:
> > +self.all_type_or_protocols = True
> > +elif type(type_or_protocol) == str:
> > +if type_or_protocol in network_protocol_keywords:
> > +self.type_or_protocol = type_or_protocol
> > +elif type_or_protocol in network_type_keywords:
> > +if self.all_domains:
> > +raise AppArmorException('Passing type %s to
> > NetworkRule without specifying a domain keyword is not allowed' %
> > str(type_or_protocol))
> 
> str(type_or_protocol) not required.

Right.

> +self.type_or_protocol = type_or_protocol
> 
> > +else:
> > +raise AppArmorBug('Passed unknown type_or_protocol
> > to NetworkRule: %s' % str(type_or_protocol))
> 
> str(type_or_protocol) not required. #copy paste reviews

;-)

> > +def is_equal_localvars(self, rule_obj):
> > +'''compare if rule-specific variables are equal'''
> > +
> > +if not type(rule_obj) == NetworkR

Re: [apparmor] [patch 1/3] Add NetworkRule and NetworkRuleset classes

2015-04-15 Thread Kshitij Gupta
Hello,


On Wed, Apr 15, 2015 at 3:07 AM, Christian Boltz  wrote:

> Hello,
>
> this patch adds utils/apparmor/rule/network.py with the NetworkRule and
> NetworkRuleset classes. These classes are meant to handle network rules.
>
> In comparison to the existing code in aa.py, relevant news are:
> - the keywords are checked against a list of allowed domains, types and
>   protocols (these lists are based on what the utils/vim/Makefile
>   generates - on the long term an autogenerated file with the keywords
>   for all rule types would be nice ;-)
>
In theory you can have a script generate a python module that solely
contains these keywords, which can be imported in here. Sounds pretty
trivial ;-)


> - there are variables for domain and type_or_protocol instead of
>   first_param and second_param. (If someone is bored enough to map the
>   protocol "shortcuts" to their expanded meaning, that shouldn't be too
>   hard.)
> - (obviously) more readable code because we have everything at one place
>   now
>
yay!


> - some bugs are fixed along the way (for example, "network foo" will now
>   be kept, not "network foo bar" - see my last mail about
>   write_net_rules() for details)
>
>
>
> [ 44-add-NetworkRule-and-NetworkRuleset-classes.diff ]
>
> === added file 'utils/apparmor/rule/network.py'
> --- utils/apparmor/rule/network.py  1970-01-01 00:00:00 +
> +++ utils/apparmor/rule/network.py  2015-04-14 20:47:40 +
> @@ -0,0 +1,210 @@
> +#!/usr/bin/env python
> +# --
> +#Copyright (C) 2013 Kshitij Gupta 
> +#Copyright (C) 2015 Christian Boltz 
> +#
> +#This program is free software; you can redistribute it and/or
> +#modify it under the terms of version 2 of the GNU General Public
> +#License as published by the Free Software Foundation.
> +#
> +#This program is distributed in the hope that it will be useful,
> +#but WITHOUT ANY WARRANTY; without even the implied warranty of
> +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +#GNU General Public License for more details.
> +#
> +# --
> +
> +import re
> +
> +from apparmor.regex import RE_PROFILE_NETWORK
> +from apparmor.common import AppArmorBug, AppArmorException
> +from apparmor.rule import BaseRule, BaseRuleset, parse_modifiers
> +
> +# setup module translations
> +from apparmor.translations import init_translation
> +_ = init_translation()
> +
> +
> +network_domain_keywords   = [ 'unix', 'inet', 'ax25', 'ipx', 'appletalk',
> 'netrom', 'bridge', 'atmpvc', 'x25', 'inet6',
> +  'rose', 'netbeui', 'security', 'key',
> 'netlink', 'packet', 'ash', 'econet', 'atmsvc', 'rds', 'sna',
> +  'irda', 'pppox', 'wanpipe', 'llc', 'can',
> 'tipc', 'bluetooth', 'iucv', 'rxrpc', 'isdn', 'phonet',
> +  'ieee802154', 'caif', 'alg', 'nfc', 'vsock'
> ]
> +# missing in manpage: 'unix', 'rds', 'llc', 'can', 'tipc',
> 'iucv', 'rxrpc', 'isdn', 'phonet', 'ieee802154', 'caif', 'alg', 'nfc',
> 'vsock'
> +
>
comments from others on the missing types?

+network_type_keywords = ['stream', 'dgram', 'seqpacket', 'rdm', 'raw',
> 'packet']
> +network_protocol_keywords = ['tcp', 'udp', 'icmp']
> +
> +
> +RE_NETWORK_DOMAIN   = '(' + '|'.join(network_domain_keywords) + ')'
> +RE_NETWORK_TYPE = '(' + '|'.join(network_type_keywords) + ')'
> +RE_NETWORK_PROTOCOL = '(' + '|'.join(network_protocol_keywords) + ')'
>
neat!


> +
> +RE_NETWORK_DETAILS  = re.compile(
> +'^\s*(' +
> +'(?P' + RE_NETWORK_DOMAIN + ')(\s+(?P'
> + RE_NETWORK_TYPE + '|' + RE_NETWORK_PROTOCOL + '))?' + # domain, optional
> type or protocol
>
exercising new/larger monitor privileges?  ;-)
can be split into two lines I think.

+'|' + # or
> +'(?P' + RE_NETWORK_PROTOCOL + ')' + # protocol only
> +')\s*$')
>
The leading and trailing \s* become superfluous as __parse has:
rule_details = matches.group('details').strip()

+

+
> +
> +
> +
> +
> +
>
what is the standard for whitespace separation? 7 seems a bit much.

+class NetworkRule(BaseRule):
> +'''Class to handle and store a single network rule'''
> +
> +# Nothing external should reference this class, all external users
> +# should reference the class field NetworkRule.ALL
> +class __NetworkAll(object):
> +pass
> +
>
+ALL = __NetworkAll
> +
> +def __init__(self, domain, type_or_protocol, audit=False, deny=False,
> allow_keyword=False,
> + comment='', log_event=None):
> +
> +'''
> +   NETWORK RULE = 'network' [ [ DOMAIN [ TYPE | PROTOCOL ] ] | [
> PROTOCOL ] ] ','
> +'''
> +
> +super(NetworkRule, self).__init__(audit=audit, deny=deny,
> + allow_keyword=allow_keyword,
> + comment=comment,
> +