~ubuntu-branches/debian/stretch/ufw/stretch

« back to all changes in this revision

Viewing changes to src/frontend.py

  • Committer: Package Import Robot
  • Author(s): Jamie Strandboge
  • Date: 2013-11-26 12:51:51 UTC
  • mfrom: (0.2.7)
  • Revision ID: package-import@ubuntu.com-20131126125151-y3ukoqrgsluhsrh0
Tags: 0.33-1
* New upstream release (Closes: 711711, Closes: 691135, Closes: 704728).
  Sync back up with Ubuntu (all changes here except for Polish debconf
  translation and Standards-Version already in Ubuntu). Add the following
  patches from Ubuntu which can be dropped in 0.34:
  - debian/patches/0002-lp1044361.patch: move netfilter capabilities
    checking into initcaps(), and call initcaps() only when we need it
  - 0003-fix-typeerror-on-error.patch: fix TypeError on error when using
    zh_CN
  - debian/patches/0004-lp1039729.patch: Skip get_netfilter_capabilities()
    with ipv6 if ipv6 is disabled
  - debian/patches/0005-lp1191197.patch: add check for -m rt --rt-type 0
* debian/po/pl.po: add Polish translation of debconf templates. Thanks to
  Michal Kulach (Closes: 667942)
* debian/watch: use https instead of http
* debian/(after|before)6.rules.md5sum: adjust for recently missed shipped
  configurations
* debian/control:
  - clean up Depends and Build-Depends
  - Build-Depends on python3
  - add python-ufw for installing python2 modules
  - add X-Python3-Version: >= 3.2
  - update Standards-Version to 3.9.4
* add debian/python-ufw.install
* debian/rules:
  - use --install-layout=deb
  - adjust PYTHON to use python3
  - adjust PYVERS to use py3versions
  - add PYTHON2
  - run tests for both PYTHON and PYTHON2
  - run setup.py with both PYTHON and PYTHON2
  - use dh_python3 for ufw
  - use dh_python2 for python-ufw
* debian/ufw.lintian-overrides
  - remove old unneeded override
  - add postrm-does-not-call-updaterc.d-for-init.d-script since Ubuntu's
    debhelper adds code to postinst that does nothing on Ubuntu, but doesn't
    add the corresponding code to postrm

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
'''frontend.py: frontend interface for ufw'''
2
2
#
3
 
# Copyright 2008-2011 Canonical Ltd.
 
3
# Copyright 2008-2012 Canonical Ltd.
4
4
#
5
5
#    This program is free software: you can redistribute it and/or modify
6
6
#    it under the terms of the GNU General Public License version 3,
21
21
 
22
22
from ufw.common import UFWError
23
23
import ufw.util
24
 
from ufw.util import error, warn
 
24
from ufw.util import error, warn, msg
25
25
from ufw.backend_iptables import UFWBackendIptables
26
26
import ufw.parser
27
27
 
52
52
 
53
53
    # Show commands
54
54
    for i in ['raw', 'before-rules', 'user-rules', 'after-rules', \
55
 
              'logging-rules', 'builtins', 'listening']:
 
55
              'logging-rules', 'builtins', 'listening', 'added']:
56
56
        p.register_command(ufw.parser.UFWCommandShow(i))
57
57
 
58
58
    # Rule commands
71
71
            argv.insert(idx, 'rule')
72
72
 
73
73
    if len(argv) < 2 or ('--dry-run' in argv and len(argv) < 3):
74
 
        print >> sys.stderr, "ERROR: not enough args"
75
 
        sys.exit(1)
 
74
        error("not enough args")
76
75
 
77
76
    try:
78
77
        pr = p.parse_command(argv[1:])
79
 
    except UFWError, e:
80
 
        print >> sys.stderr, "ERROR: %s" % (e.value)
81
 
        sys.exit(1)
 
78
    except UFWError as e:
 
79
        error("%s" % (e.value))
82
80
    except Exception:
83
 
        print >> sys.stderr, "Invalid syntax"
 
81
        error("Invalid syntax", do_exit=False)
84
82
        raise
85
83
 
86
84
    return pr
87
85
 
88
86
def get_command_help():
89
87
    '''Print help message'''
90
 
    msg = _('''
 
88
    help_msg = _('''
91
89
Usage: %(progname)s %(command)s
92
90
 
93
91
%(commands)s:
144
142
         'appupdate': "app update PROFILE", \
145
143
         'appdefault': "app default ARG"}))
146
144
 
147
 
    return (msg)
 
145
    return (help_msg)
148
146
 
149
147
 
150
148
class UFWFrontend:
183
181
            try:
184
182
                self.backend.set_default(self.backend.files['conf'], \
185
183
                                         "ENABLED", config_str)
186
 
            except UFWError, e:
 
184
            except UFWError as e:
187
185
                error(e.value)
188
186
 
189
187
        error_str = ""
190
188
        if enabled:
191
189
            try:
192
190
                self.backend.start_firewall()
193
 
            except UFWError, e:
 
191
            except UFWError as e:
194
192
                if changed:
195
193
                    error_str = e.value
196
194
 
200
198
                try:
201
199
                    self.backend.set_default(self.backend.files['conf'], \
202
200
                                             "ENABLED", "no")
203
 
                except UFWError, e:
 
201
                except UFWError as e:
204
202
                    error(e.value)
205
203
 
206
204
                # Report the error
210
208
        else:
211
209
            try:
212
210
                self.backend.stop_firewall()
213
 
            except UFWError, e:
 
211
            except UFWError as e:
214
212
                error(e.value)
215
213
 
216
214
            res = _("Firewall stopped and disabled on system startup")
225
223
            if self.backend.is_enabled():
226
224
                self.backend.stop_firewall()
227
225
                self.backend.start_firewall()
228
 
        except UFWError, e:
 
226
        except UFWError as e:
229
227
            error(e.value)
230
228
 
231
229
        return res
235
233
        res = ""
236
234
        try:
237
235
            res = self.backend.set_loglevel(level)
238
 
        except UFWError, e:
 
236
        except UFWError as e:
239
237
            error(e.value)
240
238
 
241
239
        return res
244
242
        '''Shows status of firewall'''
245
243
        try:
246
244
            out = self.backend.get_status(verbose, show_count)
247
 
        except UFWError, e:
 
245
        except UFWError as e:
248
246
            error(e.value)
249
247
 
250
248
        return out
253
251
        '''Shows raw output of firewall'''
254
252
        try:
255
253
            out = self.backend.get_running_raw(rules_type)
256
 
        except UFWError, e:
 
254
        except UFWError as e:
257
255
            error(e.value)
258
256
 
259
257
        return out
269
267
 
270
268
        rules = self.backend.get_rules()
271
269
 
272
 
        protocols = d.keys()
 
270
        protocols = list(d.keys())
273
271
        protocols.sort()
274
272
        for proto in protocols:
275
273
            if not self.backend.use_ipv6() and proto in ['tcp6', 'udp6']:
276
274
                continue
277
275
            res += "%s:\n" % (proto)
278
 
            ports = d[proto].keys()
 
276
            ports = list(d[proto].keys())
279
277
            ports.sort()
280
278
            for port in ports:
281
279
                for item in d[proto][port]:
321
319
 
322
320
        return res
323
321
 
 
322
    def get_show_added(self):
 
323
        '''Shows added rules to the firewall'''
 
324
        rules = self.backend.get_rules()
 
325
 
 
326
        out = _("Added user rules (see 'ufw status' for running firewall):")
 
327
 
 
328
        if len(rules) == 0:
 
329
            return out + _("\n(None)")
 
330
 
 
331
        added = []
 
332
        for r in self.backend.get_rules():
 
333
            rstr = ufw.parser.UFWCommandRule.get_command(r)
 
334
 
 
335
            # Approximate the order the rules were added. Since rules is
 
336
            # internally rules4 + rules6, IPv6 only rules will show up after
 
337
            # other rules. In terms of rule ordering in the kernel, this is
 
338
            # an equivalent ordering.
 
339
            if rstr in added:
 
340
                continue
 
341
 
 
342
            added.append(rstr)
 
343
            out += "\nufw %s" % rstr
 
344
 
 
345
        return out
 
346
 
324
347
    def set_rule(self, rule, ip_version):
325
348
        '''Updates firewall with rule'''
326
349
        res = ""
465
488
                    else:
466
489
                        err_msg = _("Invalid IP version '%s'") % (ip_version)
467
490
                        raise UFWError(err_msg)
468
 
            except UFWError, e:
 
491
            except UFWError as e:
469
492
                err_msg = e.value
470
493
                set_error = True
471
494
                break
484
507
            # If error and more than one rule, delete the successfully added
485
508
            # rules in reverse order
486
509
            undo_error = False
487
 
            indexes = range(count+1)
 
510
            indexes = list(range(count+1))
488
511
            indexes.reverse()
489
512
            for j in indexes:
490
513
                if count > 0 and rules[j]:
540
563
                       "(%(yes)s|%(no)s)? ") % ({'rule': rstr, \
541
564
                                                 'yes': self.yes, \
542
565
                                                 'no': self.no})
543
 
            os.write(sys.stdout.fileno(), prompt)
 
566
            msg(prompt, output=sys.stdout, newline=False)
544
567
            ans = sys.stdin.readline().lower().strip()
545
568
            if ans != "y" and ans != self.yes and ans != self.yes_full:
546
569
                proceed = False
582
605
            tmp = action.split('-')[1]
583
606
            if tmp == "listening":
584
607
                res = self.get_show_listening()
 
608
            elif tmp == "added":
 
609
                res = self.get_show_added()
585
610
            else:
586
611
                res = self.get_show_raw(tmp)
587
612
        elif action == "status-numbered":
608
633
                    if tmp != rule.dapp:
609
634
                        rule.dapp = tmp
610
635
                        rule.set_port(tmp, "dst")
611
 
                except UFWError, e:
 
636
                except UFWError as e:
612
637
                    # allow for the profile being deleted (LP: #407810)
613
638
                    if not rule.remove:
614
639
                        error(e.value)
622
647
                    if tmp != rule.sapp:
623
648
                        rule.sapp = tmp
624
649
                        rule.set_port(tmp, "dst")
625
 
                except UFWError, e:
 
650
                except UFWError as e:
626
651
                    # allow for the profile being deleted (LP: #407810)
627
652
                    if not rule.remove:
628
653
                        error(e.value)
642
667
        res = ""
643
668
        try:
644
669
            res = self.backend.set_default_application_policy(policy)
645
 
        except UFWError, e:
 
670
        except UFWError as e:
646
671
            error(e.value)
647
672
 
648
673
        return res
649
674
 
650
675
    def get_application_list(self):
651
676
        '''Display list of known application profiles'''
652
 
        names = self.backend.profiles.keys()
 
677
        names = list(self.backend.profiles.keys())
653
678
        names.sort()
654
679
        rstr = _("Available applications:")
655
680
        for n in names:
660
685
        '''Display information on profile'''
661
686
        names = []
662
687
        if pname == "all":
663
 
            names = self.backend.profiles.keys()
 
688
            names = list(self.backend.profiles.keys())
664
689
            names.sort()
665
690
        else:
666
691
            if not ufw.applications.valid_profile_name(pname):
670
695
 
671
696
        rstr = ""
672
697
        for name in names:
673
 
            if not self.backend.profiles.has_key(name) or \
 
698
            if name not in self.backend.profiles or \
674
699
               not self.backend.profiles[name]:
675
700
                err_msg = _("Could not find profile '%s'") % (name)
676
701
                raise UFWError(err_msg)
719
744
            allow_reload = False
720
745
 
721
746
        if profile == "all":
722
 
            profiles = self.backend.profiles.keys()
 
747
            profiles = list(self.backend.profiles.keys())
723
748
            profiles.sort()
724
749
            for p in profiles:
725
750
                (tmp, found) = self.backend.update_app_rule(p)
779
804
        except Exception:
780
805
            raise
781
806
 
782
 
        if pr.data.has_key('rule'):
 
807
        if 'rule' in pr.data:
783
808
            rstr = self.do_action(pr.action, pr.data['rule'], \
784
809
                                  pr.data['iptype'])
785
810
        else:
826
851
            prompt = _("Command may disrupt existing ssh connections. " \
827
852
                       "Proceed with operation (%(yes)s|%(no)s)? ") % \
828
853
                       ({'yes': self.yes, 'no': self.no})
829
 
            os.write(sys.stdout.fileno(), prompt)
 
854
            msg(prompt, output=sys.stdout, newline=False)
830
855
            ans = sys.stdin.readline().lower().strip()
831
856
            if ans != "y" and ans != self.yes and ans != self.yes_full:
832
857
                proceed = False
846
871
                       ({'yes': self.yes, 'no': self.no})
847
872
 
848
873
        if self.backend.do_checks and not force:
849
 
            os.write(sys.stdout.fileno(), ufw.util.wrap_text(prompt))
 
874
            msg(ufw.util.wrap_text(prompt), output=sys.stdout, newline=False)
850
875
            ans = sys.stdin.readline().lower().strip()
851
876
            if ans != "y" and ans != self.yes and ans != self.yes_full:
852
877
                res = _("Aborted")