[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1036306: marked as done (unblock: ufw/0.36.2-1)



Your message dated Fri, 26 May 2023 22:39:10 +0200
with message-id <7b31e0f8-4bf9-9dd8-74f7-1f7ab36fdd94@debian.org>
and subject line Re: Bug#1036306: unblock: ufw/0.36.2-1
has caused the Debian Bug report #1036306,
regarding unblock: ufw/0.36.2-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1036306: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1036306
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package ufw

It seems that adduser 3.133 has caused problems for a lot of packages in sid,
including ufw. See:

https://piuparts.debian.org/sid/fail/adduser_3.133.log
https://piuparts.debian.org/sid/fail/
https://piuparts.debian.org/sid/fail/ufw_0.36.2-1.log
https://piuparts.debian.org/sid/fail/...

In the case of ufw, it ships a logrotate file and logrotate gets installed,
which pulls in adduser, but adduser can't be removed and piuparts fails:

0m18.6s DEBUG: Starting command: ['chroot', '/srv/piuparts.debian.org/tmp/tmpwv4fmpa7', 'apt-get', 'install', '-y', 'logrotate']
0m19.9s DUMP:
  Reading package lists...
  Building dependency tree...
  Reading state information...
  The following additional packages will be installed:
    adduser cron cron-daemon-common libpopt0 sensible-utils
...
m20.2s ERROR: Command failed (status=1): ['chroot', '/srv/piuparts.debian.org/tmp/tmpwv4fmpa7', 'dpkg', '--purge', 'adduser', 'cron', 'cron-daemon-common', 'libpopt0:amd64', 'logrotate', 'sensible-utils']
  dpkg: error processing package adduser (--purge):
   this is a protected package; it should not be removed
...

As mentioned, there seem to be several packages in this state. ufw has shipped
a logrotate file for years and this isn't new to ufw 0.36.2-1. 

[ Reason ]
ufw did not cause adduser to be unremovable, and adduser being unremovable
should not affect ufw's migration.

[ Impact ]
Bug fixes and translations will not be available in bookworm (I am upstream ufw
and I cut 0.36.2 specifically for bookworm users).

[ Tests ]
Build tests (unit and functional) and autopkgtests pass.

[ Risks ]
Leaf package.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing


unblock ufw/0.36.2-1
diff -Nru ufw-0.36.1/ChangeLog ufw-0.36.2/ChangeLog
--- ufw-0.36.1/ChangeLog	2021-09-18 20:29:52.000000000 -0500
+++ ufw-0.36.2/ChangeLog	2023-05-18 08:45:35.000000000 -0500
@@ -1,3 +1,23 @@
+ufw (0.36.2) RELEASED; urgency=medium
+
+  * src/ufw-init-functions: set default policy after loading rules. Thanks to
+    Mauricio Faria de Oliveira. (LP: #1946804)
+  * doc/ufw.8:
+    - document 'insert' and 'prepend' can't be used to update comments
+      (LP: #1927737)
+  * src/backend_iptables.py: remove unreachable code (LP: #1927734)
+  * src/util.py:
+    - properly parse /proc/pid/stat for WSL (LP: #2015645)
+    - mitigate odd length string with unhexlify (Closes: 1034568)
+    - support vrrp protocol (LP: #1996636)
+  * add locales/po/ro.po. Thanks Remus-Gabriel Chelu (Closes: 1034119)
+  * add '-h' and show help with no args (LP: #1965462)
+  * src/backend.py: add get_rules_ipv4() and get_rules_ipv6() (LP: #1951018)
+  * tests/check-requirements: update for python 3.10+
+  * tests/root: normalize 'ACCEPT {all,tcp}' and 'ACCEPT N' for newer systems
+
+ -- Jamie Strandboge <jdstrand@ubuntu.com>  Thu, 18 May 2023 08:45:30 -0500
+
 ufw (0.36.1) RELEASED; urgency=medium
 
   * snap packaging updates:
diff -Nru ufw-0.36.1/debian/changelog ufw-0.36.2/debian/changelog
--- ufw-0.36.1/debian/changelog	2022-10-15 05:54:27.000000000 -0500
+++ ufw-0.36.2/debian/changelog	2023-05-18 09:03:07.000000000 -0500
@@ -1,3 +1,30 @@
+ufw (0.36.2-1) unstable; urgency=medium
+
+  * New upstream release (LP: #1946804, LP: #1927737, LP: #1927734,
+    LP: #2015645, LP: #1996636, LP: #1965462, LP: #1951018, Closes: 1034568,
+    Closes: 1034119). Drop the following (included upstream):
+    - 0002-fix-copyright.patch
+    - 0003-python3-versions.patch
+    - 0004-set-default-policy-after-load.patch
+  * Remaining changes:
+    - 0001-optimize-boot.patch
+  * add new debian/po/ro.po. Thanks Remus-Gabriel Chelu (Closes: 1033758)
+  * debian/control:
+    - Breaks with iptables-persistent and netfilter-persistent. When ufw is
+      installed, it is not enabled by default, so it doesn't interfere with
+      other firewall software (until it is enabled). In contrast,
+      iptables-persistent and netfilter-persistent install enabled, which
+      interferes with ufw. Add a breaks on these to avoid them being
+      co-installed with ufw (and causing problems for users).
+    - use Python-Version instead of XB-Python-Version
+    - remove Depends on obsolete lsb-base
+  * ufw.lintian-overrides:
+    - update for breaks-without-version iptables-persistent and
+      netfilter-persistent
+    - update for newer lintian
+
+ -- Jamie Strandboge <jdstrand@ubuntu.com>  Thu, 18 May 2023 14:03:07 +0000
+
 ufw (0.36.1-4.1) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru ufw-0.36.1/debian/control ufw-0.36.2/debian/control
--- ufw-0.36.1/debian/control	2021-09-19 00:46:12.000000000 -0500
+++ ufw-0.36.2/debian/control	2023-05-16 09:37:21.000000000 -0500
@@ -13,7 +13,7 @@
  po-debconf,
  python3 (>= 3.2),
  python3-distutils
-Standards-Version: 4.6.0.1
+Standards-Version: 4.6.2
 Homepage: https://launchpad.net/ufw
 Vcs-Browser: https://git.launchpad.net/ufw?h=debian/master
 Vcs-Git: https://git.launchpad.net/ufw -b debian/master
@@ -23,11 +23,11 @@
 Suggests: rsyslog
 Depends:
  iptables,
- lsb-base (>= 3.0-6),
  ucf,
  ${python3:Depends},
  ${misc:Depends}
-XB-Python-Version: ${python3:Versions}
+Breaks: iptables-persistent, netfilter-persistent
+Python-Version: ${python3:Versions}
 Description: program for managing a Netfilter firewall
  The Uncomplicated FireWall is a front-end for iptables, to make managing a
  Netfilter firewall easier. It provides a command line interface with syntax
diff -Nru ufw-0.36.1/debian/patches/0002-fix-copyright.patch ufw-0.36.2/debian/patches/0002-fix-copyright.patch
--- ufw-0.36.1/debian/patches/0002-fix-copyright.patch	2021-09-19 00:46:12.000000000 -0500
+++ ufw-0.36.2/debian/patches/0002-fix-copyright.patch	1969-12-31 18:00:00.000000000 -0600
@@ -1,28 +0,0 @@
-commit b1d840a4a23bd586059d6654fb60a42114ae7b92
-Author: Jamie Strandboge <jdstrand@ubuntu.com>
-Date:   Sun Sep 19 01:09:36 2021 -0500
-
-    src/ufw: update copyright year
-
-diff --git a/src/ufw b/src/ufw
-index 115d294..7d72395 100755
---- a/src/ufw
-+++ b/src/ufw
-@@ -2,7 +2,7 @@
- #
- # ufw: front-end for Linux firewalling (cli)
- #
--# Copyright 2008-2018 Canonical Ltd.
-+# Copyright 2008-2021 Canonical Ltd.
- #
- #    This program is free software: you can redistribute it and/or modify
- #    it under the terms of the GNU General Public License version 3,
-@@ -108,7 +108,7 @@ if __name__ == "__main__":
-         sys.exit(0)
-     elif pr.action == "version" or pr.action == "--version":
-         msg(ufw.common.programName + " " + version)
--        msg("Copyright 2008-2018 Canonical Ltd.")
-+        msg("Copyright 2008-2021 Canonical Ltd.")
-         sys.exit(0)
- 
-     try:
diff -Nru ufw-0.36.1/debian/patches/0003-python3-versions.patch ufw-0.36.2/debian/patches/0003-python3-versions.patch
--- ufw-0.36.1/debian/patches/0003-python3-versions.patch	2021-09-19 00:46:12.000000000 -0500
+++ ufw-0.36.2/debian/patches/0003-python3-versions.patch	1969-12-31 18:00:00.000000000 -0600
@@ -1,15 +0,0 @@
-Author: Matthias Klose <doko@debian.org>
-Description: Fix python version check for Python >= 3.9
-Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=975912
-Forwarded: yes
---- a/tests/check-requirements
-+++ b/tests/check-requirements
-@@ -59,7 +59,7 @@ for exe in python3 python2 python ; do
-         echo "pass (binary: $exe, version: $v, py2)"
-         found_python="yes"
-         break
--    elif echo "$v" | grep -q "^3.[2-8]"; then
-+    elif echo "$v" | grep -q "^3.[1-9][0-9]*"; then
-         echo "pass (binary: $exe, version: $v, py3)"
-         found_python="yes"
-         break
diff -Nru ufw-0.36.1/debian/patches/0004-set-default-policy-after-load.patch ufw-0.36.2/debian/patches/0004-set-default-policy-after-load.patch
--- ufw-0.36.1/debian/patches/0004-set-default-policy-after-load.patch	2021-10-13 14:00:26.000000000 -0500
+++ ufw-0.36.2/debian/patches/0004-set-default-policy-after-load.patch	1969-12-31 18:00:00.000000000 -0600
@@ -1,93 +0,0 @@
-Origin: upstream, https://git.launchpad.net/ufw/commit/?id=4d25bd6635a493ae10c1984bfe16fb31e3903198
-Bug-Ubuntu: https://bugs.launchpad.net/bugs/1946804
-From: Mauricio Faria de Oliveira <mfo@canonical.com>
-Date: Tue, 12 Oct 2021 18:57:40 -0300
-Subject: [PATCH] src/ufw-init-functions: set default policy after loading
- rules
-
-If default input policy of DROP (default setting in ufw) is set
-before loading rules to allow a network root filesystem to work,
-it freezes before loading them, and the boot process stalls.
-
-Just set default policy after loading rules, as the snippet for
-ip[6]tables-restore has -n/--noflush, which doesn't flush other
-rules in the builtin chains.
-
-The output of iptables -L is identical before/after.
-
-https://bugs.launchpad.net/bugs/1946804
-
-Signed-off-by: Mauricio Faria de Oliveira <mfo@canonical.com>
----
- src/ufw-init-functions | 48 ++++++++++++++++++++++--------------------
- 1 file changed, 25 insertions(+), 23 deletions(-)
-
-diff --git a/src/ufw-init-functions b/src/ufw-init-functions
-index feac8e203c1d..f0dd7f59f4c2 100755
---- a/src/ufw-init-functions
-+++ b/src/ufw-init-functions
-@@ -168,29 +168,6 @@ ufw_start() {
-             AFTER_RULES="$RULES_PATH/after${type}.rules"
-             USER_RULES="$USER_PATH/user${type}.rules"
- 
--            # set the default policy
--            input_pol="$DEFAULT_INPUT_POLICY"
--            if [ "$DEFAULT_INPUT_POLICY" = "REJECT" ]; then
--                input_pol="DROP"
--            fi
--
--            output_pol="$DEFAULT_OUTPUT_POLICY"
--            if [ "$DEFAULT_OUTPUT_POLICY" = "REJECT" ]; then
--                output_pol="DROP"
--            fi
--
--            forward_pol="$DEFAULT_FORWARD_POLICY"
--            if [ "$DEFAULT_FORWARD_POLICY" = "REJECT" ]; then
--                forward_pol="DROP"
--            fi
--
--            printf "*filter\n"\
--"# builtin chains\n"\
--":INPUT %s [0:0]\n"\
--":FORWARD %s [0:0]\n"\
--":OUTPUT %s [0:0]\n"\
--"COMMIT\n" $input_pol $forward_pol $output_pol | $exe-restore -n || error="yes"
--
-             # flush the chains (if they exist)
-             if $exe -L ufw${type}-before-logging-input -n >/dev/null 2>&1 ; then
-                 delete_chains $type || error="yes"
-@@ -378,6 +355,31 @@ ufw_start() {
-                 out="${out}\nCouldn't find '$USER_RULES'"
-                 error="yes"
-             fi
-+
-+            # set the default policy
-+            # (do this after loading rules so not to break
-+            # network rootfs w/ INPUT DROP during ufw init.)
-+            input_pol="$DEFAULT_INPUT_POLICY"
-+            if [ "$DEFAULT_INPUT_POLICY" = "REJECT" ]; then
-+                input_pol="DROP"
-+            fi
-+
-+            output_pol="$DEFAULT_OUTPUT_POLICY"
-+            if [ "$DEFAULT_OUTPUT_POLICY" = "REJECT" ]; then
-+                output_pol="DROP"
-+            fi
-+
-+            forward_pol="$DEFAULT_FORWARD_POLICY"
-+            if [ "$DEFAULT_FORWARD_POLICY" = "REJECT" ]; then
-+                forward_pol="DROP"
-+            fi
-+
-+            printf "*filter\n"\
-+"# builtin chains\n"\
-+":INPUT %s [0:0]\n"\
-+":FORWARD %s [0:0]\n"\
-+":OUTPUT %s [0:0]\n"\
-+"COMMIT\n" $input_pol $forward_pol $output_pol | $exe-restore -n || error="yes"
-         done
- 
-         if [ ! -z "$IPT_SYSCTL" ] && [ -s "$IPT_SYSCTL" ]; then
--- 
-2.30.2
-
diff -Nru ufw-0.36.1/debian/patches/series ufw-0.36.2/debian/patches/series
--- ufw-0.36.1/debian/patches/series	2021-10-13 14:02:20.000000000 -0500
+++ ufw-0.36.2/debian/patches/series	2023-05-16 09:03:37.000000000 -0500
@@ -1,4 +1 @@
 0001-optimize-boot.patch
-0002-fix-copyright.patch
-0003-python3-versions.patch
-0004-set-default-policy-after-load.patch
diff -Nru ufw-0.36.1/debian/po/ro.po ufw-0.36.2/debian/po/ro.po
--- ufw-0.36.1/debian/po/ro.po	1969-12-31 18:00:00.000000000 -0600
+++ ufw-0.36.2/debian/po/ro.po	2023-05-16 08:59:14.000000000 -0500
@@ -0,0 +1,125 @@
+# Mesajele în limba română pentru pachetul ufw.
+# Romanian translation of ufw.
+# Copyright © 2023 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the ufw package.
+#
+# Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>, 2023.
+#
+# Cronologia traducerii fișierului „ufw”:
+# Traducerea inițială, făcută de R-GC, pentru versiunea ufw 0.36.1-4.1(2009-06-16).
+# Actualizare a traducerii pentru versiunea Y, făcută de X, Y(anul).
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ufw 0.36.1-4.1\n"
+"Report-Msgid-Bugs-To: ufw@packages.debian.org\n"
+"POT-Creation-Date: 2009-06-16 23:11+0100\n"
+"PO-Revision-Date: 2023-03-26 21:16+0200\n"
+"Last-Translator: Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>\n"
+"Language-Team: Romanian <debian-l10n-romanian@lists.debian.org>\n"
+"Language: ro\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==0 || (n!=1 && n%100>=1 && "
+"n%100<=19) ? 1 : 2);\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"X-Generator: Poedit 3.2.2\n"
+
+#. Type: error
+#. Description
+#: ../templates:2001
+msgid "Existing configuration found"
+msgstr "S-a găsit o configurație existentă"
+
+#. Type: error
+#. Description
+#: ../templates:2001
+msgid ""
+"An existing configuration for ufw has been found. Existing rules must be "
+"managed manually."
+msgstr ""
+"O configurație existentă pentru «ufw» a fost găsită. Regulile existente trebuie "
+"gestionate manual."
+
+#. Type: error
+#. Description
+#: ../templates:2001
+msgid "You should read the ufw(8) manpage for details about ufw configuration."
+msgstr ""
+"Ar trebui să citiți pagina de manual ufw(8) pentru detalii despre configurarea "
+"„ufw”."
+
+#. Type: boolean
+#. Description
+#: ../templates:3001
+msgid "Start ufw automatically?"
+msgstr "Doriți să porniți automat serviciul «ufw»?"
+
+#. Type: boolean
+#. Description
+#: ../templates:3001
+msgid ""
+"If you choose this option, the rules you are about to set will be enabled "
+"during system startup so that this host is protected as early as possible."
+msgstr ""
+"Dacă alegeți această opțiune, regulile pe care urmează să le stabiliți vor fi "
+"activate în timpul pornirii sistemului, astfel încât această gazdă să fie "
+"protejată cât mai curând posibil."
+
+#. Type: boolean
+#. Description
+#: ../templates:3001
+msgid "To protect this host immediately, you must start ufw manually."
+msgstr ""
+"Pentru a proteja această gazdă imediat, trebuie să porniți manual serviciul "
+"«ufw»."
+
+#. Type: multiselect
+#. Description
+#: ../templates:4001
+msgid "Authorized services:"
+msgstr "Servicii autorizate:"
+
+#. Type: multiselect
+#. Description
+#: ../templates:4001
+msgid ""
+"Please choose the services that should be available for incoming connections."
+msgstr ""
+"Alegeți serviciile care ar trebui să fie disponibile pentru conexiunile de "
+"intrare."
+
+#. Type: multiselect
+#. Description
+#: ../templates:4001
+msgid "Other services may be specified in the next configuration step."
+msgstr "Alte servicii pot fi specificate în următorul pas de configurare."
+
+#. Type: string
+#. Description
+#: ../templates:5001
+msgid "Additional authorized services:"
+msgstr "Servicii suplimentare autorizate:"
+
+#. Type: string
+#. Description
+#: ../templates:5001
+msgid ""
+"Please enter a space separated list of any additional ports you would like to "
+"open. You may use a service name (as found in /etc/services), a port number, or "
+"a port number with protocol."
+msgstr ""
+"Introduceți o listă separată de spații cu porturile suplimentare pe care doriți "
+"să le deschideți. Puteți utiliza un nume de serviciu (cum se găsește în „/etc/"
+"services”), un număr de port sau un număr de port cu protocol."
+
+#. Type: string
+#. Description
+#: ../templates:5001
+msgid ""
+"Example: to allow a web server, port 53 and tcp port 22, you should enter \"www "
+"53 22/tcp\"."
+msgstr ""
+"Exemplu: pentru a permite un server web, portul 53 și portul tcp 22, ar trebui "
+"să introduceți „www 53 22/tcp”."
diff -Nru ufw-0.36.1/debian/ufw.lintian-overrides ufw-0.36.2/debian/ufw.lintian-overrides
--- ufw-0.36.1/debian/ufw.lintian-overrides	2021-09-19 00:33:52.000000000 -0500
+++ ufw-0.36.2/debian/ufw.lintian-overrides	2023-05-16 09:46:12.000000000 -0500
@@ -1,8 +1,11 @@
 # These are intentionally not executable
-ufw binary: script-not-executable usr/share/ufw/after.init
-ufw binary: script-not-executable usr/share/ufw/before.init
+ufw: script-not-executable [usr/share/ufw/after.init]
+ufw: script-not-executable [usr/share/ufw/before.init]
 # Don't complain about 'ufw allow' rules
-ufw binary: typo-in-manual-page usr/share/man/man8/ufw.8.gz "allow to" "allow one to"
-ufw binary: spelling-error-in-changelog "allow to" "allow one to"
+ufw: spelling-error-in-changelog "allow to" "allow one to"
+ufw: mismatched-override typo-in-manual-page usr/share/man/man8/ufw.8.gz "allow to" "allow one to" [usr/share/lintian/overrides/ufw:5]
 # Don't complain about the ufw-framework man page, it gives additional details
-ufw binary: spare-manual-page usr/share/man/man8/ufw-framework.8.gz
+ufw: spare-manual-page usr/share/man/man8/ufw-framework.8.gz
+# Don't complain about breaks-without-version since we want to break on all
+ufw: breaks-without-version iptables-persistent
+ufw: breaks-without-version netfilter-persistent
diff -Nru ufw-0.36.1/doc/systemd.example ufw-0.36.2/doc/systemd.example
--- ufw-0.36.1/doc/systemd.example	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/doc/systemd.example	2023-05-18 08:07:39.000000000 -0500
@@ -1,8 +1,9 @@
 [Unit]
 Description=Uncomplicated firewall
-DefaultDependencies=no
-Wants=network-pre.target
+Documentation=man:ufw(8)
 Before=network-pre.target
+Wants=network-pre.target
+Conflicts=iptables.service ip6tables.service nftables.service firewalld.service
 
 [Service]
 Type=oneshot
diff -Nru ufw-0.36.1/doc/ufw.8 ufw-0.36.2/doc/ufw.8
--- ufw-0.36.1/doc/ufw.8	2021-09-18 20:19:03.000000000 -0500
+++ ufw-0.36.2/doc/ufw.8	2023-05-18 08:07:39.000000000 -0500
@@ -1,4 +1,4 @@
-.TH UFW: "8" "" "September 2021" "September 2021"
+.TH UFW: "8" "" "May 2023" "May 2023"
 
 .SH NAME
 ufw \- program for managing a netfilter firewall
@@ -125,7 +125,8 @@
 
 Both syntaxes support specifying a comment for the rule. For existing rules,
 specifying a different comment updates the comment and specifying '' removes
-the comment.
+the comment (note, 'insert' and 'prepend' cannot be used to update the
+comment).
 
 Example rules using the simple syntax:
 
@@ -199,6 +200,7 @@
   ah      valid without port number
   esp     valid without port number
   gre     valid without port number
+  vrrp    valid without port number
   ipv6    valid for IPv4 addresses and without port number
   igmp    valid for IPv4 addresses and without port number
 
@@ -565,6 +567,11 @@
   ufw allow to 10.0.0.1 proto ah
   ufw allow to 10.0.0.1 from 10.4.0.0/16 proto ah
 .PP
+keepalived is supported by using the 'vrrp' ('112') protocol. This protocol
+can only be used with the full syntax. For example:
+
+  ufw allow to 224.0.0.0/24 from 10.0.0.1 proto vrrp
+.PP
 In addition to the command\-line interface, \fBufw\fR also provides a
 framework which allows administrators to modify default behavior as well as
 take full advantage of netfilter. See the \fBufw\-framework\fR manual page for
@@ -576,4 +583,4 @@
 
 .SH AUTHOR
 .PP
-ufw is Copyright 2008-2021, Canonical Ltd.
+ufw is Copyright 2008-2023, Canonical Ltd.
diff -Nru ufw-0.36.1/doc/ufw-framework.8 ufw-0.36.2/doc/ufw-framework.8
--- ufw-0.36.1/doc/ufw-framework.8	2021-09-18 20:19:03.000000000 -0500
+++ ufw-0.36.2/doc/ufw-framework.8	2023-05-16 09:51:25.000000000 -0500
@@ -1,4 +1,4 @@
-.TH "UFW FRAMEWORK" "8" "" "September 2021" "September 2021"
+.TH "UFW FRAMEWORK" "8" "" "May 2023" "May 2023"
 
 .SH NAME
 ufw\-framework \- using the ufw framework
@@ -318,4 +318,4 @@
 
 .SH AUTHOR
 .PP
-ufw is Copyright 2008-2021, Canonical Ltd.
+ufw is Copyright 2008-2023, Canonical Ltd.
diff -Nru ufw-0.36.1/doc/ufw-on-snappy.8 ufw-0.36.2/doc/ufw-on-snappy.8
--- ufw-0.36.1/doc/ufw-on-snappy.8	2021-09-18 20:19:03.000000000 -0500
+++ ufw-0.36.2/doc/ufw-on-snappy.8	2023-05-16 09:51:25.000000000 -0500
@@ -1,4 +1,4 @@
-.TH "UFW ON SNAPPY" "8" "" "September 2021" "September 2021"
+.TH "UFW ON SNAPPY" "8" "" "May 2023" "May 2023"
 
 .SH NAME
 ufw snap \- using ufw as a snap
@@ -71,4 +71,4 @@
 
 .SH AUTHOR
 .PP
-ufw is Copyright 2008-2021, Canonical Ltd.
+ufw is Copyright 2008-2023, Canonical Ltd.
diff -Nru ufw-0.36.1/locales/po/ro.po ufw-0.36.2/locales/po/ro.po
--- ufw-0.36.1/locales/po/ro.po	1969-12-31 18:00:00.000000000 -0600
+++ ufw-0.36.2/locales/po/ro.po	2023-05-16 09:51:25.000000000 -0500
@@ -0,0 +1,989 @@
+# Mesajele în limba română pentru pachetul ufw.
+# Romanian translation of ufw.
+# Copyright © 2023 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the ufw package.
+#
+# Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>, 2023.
+#
+# Cronologia traducerii fișierului „ufw”:
+# Traducerea inițială, făcută de R-GC, pentru versiunea ufw 0.36.1-4.1(2018-12-14).
+# Actualizare a traducerii pentru versiunea Y, făcută de X, Y(anul).
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ufw 0.36.1-4.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2018-12-14 10:02-0600\n"
+"PO-Revision-Date: 2023-04-02 17:39+0200\n"
+"Last-Translator: Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>\n"
+"Language-Team: Romanian <debian-l10n-romanian@lists.debian.org>\n"
+"Language: ro\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==0 || (n!=1 && n%100>=1 && "
+"n%100<=19) ? 1 : 2);\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"X-Generator: Poedit 3.2.2\n"
+
+#: src/ufw:74
+msgid ": Need at least python 2.6)\n"
+msgstr ": Are nevoie de cel puțin python 2.6)\n"
+
+#: src/ufw:139 src/frontend.py:625 src/frontend.py:927
+msgid "Aborted"
+msgstr "Operația a fost anulată!"
+
+#: src/backend.py:70
+msgid "Couldn't determine iptables version"
+msgstr "Nu s-a putut determina versiunea «iptables»"
+
+#: src/backend.py:149
+msgid "problem running sysctl"
+msgstr "problemă la rularea «sysctl»"
+
+#: src/backend.py:188
+msgid "Checks disabled"
+msgstr "Verificări dezactivate"
+
+#: src/backend.py:194
+msgid "ERROR: this script should not be SUID"
+msgstr "EROARE: acest script nu ar trebui să aibă bitul SUID activat"
+
+#: src/backend.py:197
+msgid "ERROR: this script should not be SGID"
+msgstr "EROARE: acest script nu ar trebui să aibă bitul SGID activat"
+
+#: src/backend.py:202
+msgid "You need to be root to run this script"
+msgstr "Trebuie să fiți „root” pentru a rula acest script"
+
+#: src/backend.py:212
+#, python-format
+msgid "'%s' does not exist"
+msgstr "„%s” nu există"
+
+#: src/backend.py:235 src/backend_iptables.py:1416
+#, python-format
+msgid "Couldn't stat '%s'"
+msgstr "Nu s-a putut stabili starea lui „%s”"
+
+#: src/backend.py:253
+#, python-format
+msgid "uid is %(uid)s but '%(path)s' is owned by %(st_uid)s"
+msgstr "uid este %(uid)s, dar „%(path)s” este deținut de %(st_uid)s"
+
+#: src/backend.py:260
+#, python-format
+msgid "%s is world writable!"
+msgstr "%s are permisiuni de scriere pentru toți utilizatorii!"
+
+#: src/backend.py:265
+#, python-format
+msgid "%s is group writable!"
+msgstr "%s are permisiuni de scriere pentru toți membrii grupului!"
+
+#: src/backend.py:281
+#, python-format
+msgid "'%(f)s' file '%(name)s' does not exist"
+msgstr "„%(f)s” fișierul „%(name)s” nu există"
+
+#: src/backend.py:292 src/backend_iptables.py:690
+#, python-format
+msgid "Couldn't open '%s' for reading"
+msgstr "Nu s-a putut deschide „%s” pentru citire"
+
+#: src/backend.py:306
+#, python-format
+msgid "Missing policy for '%s'"
+msgstr "Lipsește politica pentru „%s”"
+
+#: src/backend.py:310
+#, python-format
+msgid "Invalid policy '%(policy)s' for '%(chain)s'"
+msgstr "Politica „%(policy)s” nu este validă pentru „%(chain)s”"
+
+#: src/backend.py:317
+msgid "Invalid option"
+msgstr "Opțiune nevalidă"
+
+#: src/backend.py:323 src/backend_iptables.py:790
+#, python-format
+msgid "'%s' is not writable"
+msgstr "„%s” nu poate fi scris"
+
+#: src/backend.py:370 src/backend_iptables.py:94
+#, python-format
+msgid "Unsupported policy '%s'"
+msgstr "Politica „%s” nu este acceptată"
+
+#: src/backend.py:373
+#, python-format
+msgid "Default application policy changed to '%s'"
+msgstr "Politica implicită de aplicație s-a schimbat în „%s”"
+
+#: src/backend.py:440
+msgid "No rules found for application profile"
+msgstr "Nu s-au găsit reguli pentru profilul aplicației"
+
+#: src/backend.py:496
+#, python-format
+msgid "Rules updated for profile '%s'"
+msgstr "S-au actualizat regulile pentru profilul „%s”"
+
+#: src/backend.py:502
+msgid "Couldn't update application rules"
+msgstr "Nu s-au putut actualiza regulile aplicației"
+
+#: src/backend.py:524
+#, python-format
+msgid "Found multiple matches for '%s'. Please use exact profile name"
+msgstr ""
+"S-au găsit mai multe potriviri pentru „%s”. Trebuie să utilizați numele exact "
+"al profilului"
+
+#: src/backend.py:527
+#, python-format
+msgid "Could not find a profile matching '%s'"
+msgstr "Nu s-a putut găsi un profil care să se potrivească cu „%s”"
+
+#: src/backend.py:594
+msgid "Logging: "
+msgstr "Jurnalizare: "
+
+#: src/backend.py:598
+msgid "unknown"
+msgstr "necunoscut"
+
+#: src/backend.py:610 src/backend_iptables.py:1284
+#, python-format
+msgid "Invalid log level '%s'"
+msgstr "Nivel de jurnalizare nevalid „%s”"
+
+#: src/backend.py:625
+msgid "Logging disabled"
+msgstr "Jurnalizare dezactivată"
+
+#: src/backend.py:627
+msgid "Logging enabled"
+msgstr "Jurnalizare activată"
+
+#: src/common.py:196
+#, python-format
+msgid "Bad port '%s'"
+msgstr "Port incorect „%s”"
+
+#: src/common.py:252
+#, python-format
+msgid "Unsupported protocol '%s'"
+msgstr "Protocol neacceptat „%s”"
+
+#: src/common.py:280
+msgid "Bad source address"
+msgstr "Adresă sursă greșită"
+
+#: src/common.py:290
+msgid "Bad destination address"
+msgstr "Adresă de destinație greșită"
+
+#: src/common.py:309
+msgid "Bad interface type"
+msgstr "Tip de interfață greșit"
+
+#: src/common.py:314
+msgid "Bad interface name: reserved character: '!'"
+msgstr "Nume de interfață greșit: caracter rezervat: '!'"
+
+#: src/common.py:318
+msgid "Bad interface name: can't use interface aliases"
+msgstr "Nume de interfață greșit: nu se pot folosi alias de interfață"
+
+#: src/common.py:322
+msgid "Bad interface name: can't use '.' or '..'"
+msgstr "Nume de interfață greșit: nu se poate folosi „.” sau „..”"
+
+#: src/common.py:326
+msgid "Bad interface name: interface name is empty"
+msgstr "Nume de interfață greșit: numele interfeței este gol"
+
+#: src/common.py:330
+msgid "Bad interface name: interface name too long"
+msgstr "Nume de interfață greșit: numele interfeței este prea lung"
+
+#: src/common.py:335
+msgid "Bad interface name"
+msgstr "Nume de interfață greșit"
+
+#: src/common.py:349
+#, python-format
+msgid "Insert position '%s' is not a valid position"
+msgstr "Poziția de inserare „%s” nu este o poziție validă"
+
+#: src/common.py:359
+#, python-format
+msgid "Invalid log type '%s'"
+msgstr "Tip de jurnalizare nevalid „%s”"
+
+#: src/common.py:367
+#, python-format
+msgid "Unsupported direction '%s'"
+msgstr "Direcția „%s” nu este acceptată"
+
+#: src/common.py:386
+msgid "Could not normalize source address"
+msgstr "Nu s-a putut normaliza adresa sursă"
+
+#: src/common.py:397
+msgid "Could not normalize destination address"
+msgstr "Nu s-a putut normaliza adresa de destinație"
+
+#: src/common.py:463
+msgid "Found exact match"
+msgstr "S-a găsit potrivirea exactă"
+
+#: src/common.py:468
+msgid "Found exact match, excepting comment"
+msgstr "S-a găsit potrivire exactă, cu excepția comentariului"
+
+#: src/common.py:472
+#, python-format
+msgid ""
+"Found non-action/non-logtype/comment match (%(xa)s/%(ya)s/'%(xc)s' %(xl)s/"
+"%(yl)s/'%(yc)s')"
+msgstr ""
+"S-a găsit potrivirea „non-action/non-logtype/comment”: (%(xa)s/%(ya)s/'%(xc)s' "
+"%(xl)s/%(yl)s/'%(yc)s'"
+
+#: src/common.py:630
+#, python-format
+msgid "Improper rule syntax ('%s' specified with app rule)"
+msgstr "Sintaxă incorectă a regulii („%s” specificată cu regula aplicației)"
+
+#: src/common.py:637
+#, python-format
+msgid "Invalid IPv6 address with protocol '%s'"
+msgstr "Adresă IPv6 nevalidă cu protocolul „%s”"
+
+#: src/common.py:643 src/util.py:84
+#, python-format
+msgid "Invalid port with protocol '%s'"
+msgstr "Port nevalid cu protocolul „%s”"
+
+#: src/parser.py:110
+#, python-format
+msgid "Cannot insert rule at position '%s'"
+msgstr "Nu se poate insera regula la poziția „%s”"
+
+#: src/parser.py:148
+msgid "Invalid interface clause"
+msgstr "Clauza de interfață nu este validă"
+
+#: src/parser.py:174
+msgid "Option 'log' not allowed here"
+msgstr "Opțiunea „log” nu este permisă aici"
+
+#: src/parser.py:178
+msgid "Option 'log-all' not allowed here"
+msgstr "Opțiunea „log-all” nu este permisă aici"
+
+#: src/parser.py:185
+msgid "Option 'comment' missing required argument"
+msgstr "Opțiunii „comment” îi lipsește argumentul necesar"
+
+#: src/parser.py:191
+msgid "Comment may not contain \"'\""
+msgstr "Comentariul nu poate conține „’”"
+
+#: src/parser.py:233 src/parser.py:359
+msgid "Port ranges must be numeric"
+msgstr "Intervalele de porturi trebuie să fie numerice"
+
+#: src/parser.py:242 src/util.py:87
+msgid "Bad port"
+msgstr "Port incorect"
+
+#: src/parser.py:245
+msgid "Wrong number of arguments"
+msgstr "Număr greșit de argumente"
+
+#: src/parser.py:249
+msgid "Need 'to' or 'from' clause"
+msgstr "Se necesită clauza „to” sau „from”"
+
+#: src/parser.py:264
+msgid "Improper rule syntax"
+msgstr "Sintaxă incorectă a regulii"
+
+#: src/parser.py:271
+#, python-format
+msgid "Invalid token '%s'"
+msgstr "Indicativ (token) nevalid „%s”"
+
+#: src/parser.py:283
+msgid "Invalid 'proto' clause"
+msgstr "Clauza „proto” nu este validă"
+
+#: src/parser.py:298
+#, python-format
+msgid "Invalid '%s' clause"
+msgstr "Clauza „%s” nu este validă"
+
+#: src/parser.py:320
+msgid "Invalid 'from' clause"
+msgstr "Clauza „from” nu este validă"
+
+#: src/parser.py:342
+msgid "Invalid 'to' clause"
+msgstr "Clauza „to” nu este validă"
+
+#: src/parser.py:347
+#, python-format
+msgid "Need 'from' or 'to' with '%s'"
+msgstr "Este nevoie de „from” sau „to” cu „%s”"
+
+#: src/parser.py:374
+msgid "Invalid 'port' clause"
+msgstr "Clauza „port” nu este validă"
+
+#: src/parser.py:383
+msgid "Mixed IP versions for 'from' and 'to'"
+msgstr "Versiuni IP amestecate pentru „from” și „to”"
+
+#: src/parser.py:400 src/parser.py:410 src/parser.py:419
+msgid "Could not find protocol"
+msgstr "Nu s-a putut găsi protocolul"
+
+#: src/parser.py:426
+msgid "Protocol mismatch (from/to)"
+msgstr "Nepotrivire protocol (from/to)"
+
+#: src/parser.py:433
+#, python-format
+msgid "Protocol mismatch with specified protocol %s"
+msgstr "Nepotrivire a protocolului cu protocolul specificat %s"
+
+#: src/parser.py:552
+msgid "'route delete NUM' unsupported. Use 'delete NUM' instead."
+msgstr ""
+"directiva „route delete NUM” nu este acceptată. Folosiți „delete NUM” în schimb."
+
+#: src/parser.py:585
+msgid "Invalid interface clause for route rule"
+msgstr "Clauza de interfață nu este validă pentru regula de rută"
+
+#: src/parser.py:884
+#, python-format
+msgid "Command '%s' already exists"
+msgstr "Comanda „%s” există deja"
+
+#: src/util.py:446
+msgid "Couldn't find pid (is /proc mounted?)"
+msgstr "Nu s-a putut găsi identificatorul de proces (pid); este „/proc” montat?"
+
+#: src/util.py:450
+#, python-format
+msgid "Couldn't find parent pid for '%s'"
+msgstr "Nu s-a putut găsi identificatorul procesului părinte (ppid) pentru „%s”"
+
+#: src/util.py:460
+#, python-format
+msgid "Couldn't find '%s'"
+msgstr "Nu s-a putut găsi „%s”"
+
+#: src/util.py:466
+#, python-format
+msgid "Could not find executable for '%s'"
+msgstr "Nu s-a putut găsi executabilul pentru „%s”"
+
+#: src/util.py:1026
+#, python-format
+msgid "Could not get statistics for '%s'"
+msgstr "Nu s-au putut obține statisticile pentru „%s”"
+
+#: src/backend_iptables.py:78
+msgid "New profiles:"
+msgstr "Profiluri noi:"
+
+#: src/backend_iptables.py:99
+#, python-format
+msgid "Unsupported policy for direction '%s'"
+msgstr "Politică neacceptată pentru direcția „%s”"
+
+#: src/backend_iptables.py:159
+#, python-format
+msgid "Default %(direction)s policy changed to '%(policy)s'\n"
+msgstr "Politica implicită %(direction)s a fost schimbată în „%(policy)s”\n"
+
+#: src/backend_iptables.py:161
+msgid "(be sure to update your rules accordingly)"
+msgstr "(asigurați-vă că vă actualizați regulile în consecință)"
+
+#: src/backend_iptables.py:168
+msgid "Checking raw iptables\n"
+msgstr "Se verifică „iptables” brute\n"
+
+#: src/backend_iptables.py:169
+msgid "Checking raw ip6tables\n"
+msgstr "Se verifică „ip6tables” brute\n"
+
+#: src/backend_iptables.py:262
+msgid "Checking iptables\n"
+msgstr "Se verifică „iptables”\n"
+
+#: src/backend_iptables.py:264
+msgid "Checking ip6tables\n"
+msgstr "Se verifică „ip6tables”\n"
+
+#: src/backend_iptables.py:267 src/backend_iptables.py:568
+msgid "problem running"
+msgstr "problemă rulând"
+
+#: src/backend_iptables.py:273
+msgid "Status: inactive"
+msgstr "Stare: inactiv"
+
+#: src/backend_iptables.py:443
+msgid "To"
+msgstr "La"
+
+#: src/backend_iptables.py:444
+msgid "From"
+msgstr "De la"
+
+#: src/backend_iptables.py:445
+msgid "Action"
+msgstr "Acțiune"
+
+#: src/backend_iptables.py:461 src/backend_iptables.py:465
+msgid "\n"
+msgstr "\n"
+
+#: src/backend_iptables.py:473
+#, python-format
+msgid "Default: %(in)s (incoming), %(out)s (outgoing), %(routed)s (routed)"
+msgstr ""
+"Implicit: %(in)s (care-intră), %(out)s (care-iese), %(routed)s (direcționat)"
+
+#: src/backend_iptables.py:481
+#, python-format
+msgid ""
+"Status: active\n"
+"%(log)s\n"
+"%(pol)s\n"
+"%(app)s%(status)s"
+msgstr ""
+"Stare: activ\n"
+"%(log)s\n"
+"%(pol)s\n"
+"%(app)s%(status)s"
+
+#: src/backend_iptables.py:485
+#, python-format
+msgid "Status: active%s"
+msgstr "Stare: activ%s"
+
+#: src/backend_iptables.py:490 src/backend_iptables.py:508
+msgid "running ufw-init"
+msgstr "rulează ufw-init"
+
+#: src/backend_iptables.py:502 src/backend_iptables.py:520
+#, python-format
+msgid ""
+"problem running ufw-init\n"
+"%s"
+msgstr ""
+"problemă la rularea ufw-init\n"
+"%s"
+
+#: src/backend_iptables.py:529
+msgid "Could not set LOGLEVEL"
+msgstr "Nu s-a putut fixa LOGLEVEL"
+
+#: src/backend_iptables.py:535
+msgid "Could not load logging rules"
+msgstr "Nu s-au putut încărca regulile de înregistrare în jurnal"
+
+# R-GC, scrie:
+# aici e vorba de „invenția” w3c/americană, de-a
+# numii o terminație/sufix de cantitate multiplă sau multiplexare cu un cuvînt nou, care în esență
+# vrea să spună: n-uplet, adică: duplet, triplet, etc
+# ******
+# iar aici, pare să fie vorba de tripletul adresei IP a
+# unei interfețe:
+# XXXX . YYY . ZZZ
+#: src/backend_iptables.py:709
+#, python-format
+msgid "Skipping malformed tuple (bad length): %s"
+msgstr "Se omite n-uplul (tuple) malformat (lungime greșită): %s"
+
+#: src/backend_iptables.py:720
+#, python-format
+msgid "Skipping malformed tuple (iface): %s"
+msgstr "Se omite n-uplul (tuple) malformat (iface): %s"
+
+#: src/backend_iptables.py:768
+#, python-format
+msgid "Skipping malformed tuple: %s"
+msgstr "Se omite n-uplul (tuple) malformat: %s"
+
+#: src/backend_iptables.py:966
+msgid "Adding IPv6 rule failed: IPv6 not enabled"
+msgstr "Adăugarea regulii IPv6 nu a reușit: IPv6 nu este activat"
+
+#: src/backend_iptables.py:970
+#, python-format
+msgid "Skipping unsupported IPv6 '%s' rule"
+msgstr "Se omite regula IPv6 „%s” neacceptată"
+
+#: src/backend_iptables.py:974
+#, python-format
+msgid "Skipping unsupported IPv4 '%s' rule"
+msgstr "Se omite regula IPv4 „%s” neacceptată"
+
+#: src/backend_iptables.py:977
+msgid "Must specify 'tcp' or 'udp' with multiple ports"
+msgstr "Trebuie să specificați „tcp” sau „udp” cu porturi multiple"
+
+#: src/backend_iptables.py:989
+msgid "Skipping IPv6 application rule. Need at least iptables 1.4"
+msgstr ""
+"Se omite regula IPv6 a aplicației. Se necesită cel puțin versiunea iptables 1.4"
+
+#: src/backend_iptables.py:994
+#, python-format
+msgid "Invalid position '%d'"
+msgstr "Poziție nevalidă „%d”"
+
+#: src/backend_iptables.py:998
+msgid "Cannot specify insert and delete"
+msgstr "Nu se pot specifica în același timp directivele „insert” și „delete”"
+
+#: src/backend_iptables.py:1001
+#, python-format
+msgid "Cannot insert rule at position '%d'"
+msgstr "Nu se poate insera regula la poziția „%d”"
+
+#: src/backend_iptables.py:1062
+msgid "Skipping inserting existing rule"
+msgstr "Se omite inserarea regulii existente"
+
+#: src/backend_iptables.py:1073 src/frontend.py:415
+msgid "Could not delete non-existent rule"
+msgstr "Nu s-a putut șterge regula inexistentă"
+
+#: src/backend_iptables.py:1078
+msgid "Skipping adding existing rule"
+msgstr "Se omite adăugarea unei reguli existente"
+
+#: src/backend_iptables.py:1094
+msgid "Couldn't update rules file"
+msgstr "Nu s-a putut actualiza fișierul cu reguli"
+
+#: src/backend_iptables.py:1099
+msgid "Rules updated"
+msgstr "Regulile au fost actualizate"
+
+#: src/backend_iptables.py:1101
+msgid "Rules updated (v6)"
+msgstr "Regulile au fost actualizate (v6)"
+
+#: src/backend_iptables.py:1109
+msgid "Rule inserted"
+msgstr "Regula a fost inserată"
+
+#: src/backend_iptables.py:1111
+msgid "Rule updated"
+msgstr "Regula a fost actualizată"
+
+#: src/backend_iptables.py:1121
+msgid " (skipped reloading firewall)"
+msgstr " (se omite reîncărcarea paravanului de protecție)"
+
+#: src/backend_iptables.py:1124
+msgid "Rule deleted"
+msgstr "Regula a fost ștearsă"
+
+#: src/backend_iptables.py:1127
+msgid "Rule added"
+msgstr "Regula a fost adăugată"
+
+#: src/backend_iptables.py:1144 src/backend_iptables.py:1235
+msgid "Could not update running firewall"
+msgstr "Nu s-a putut actualiza paravanul de protecție activ"
+
+#: src/backend_iptables.py:1199
+#, python-format
+msgid "Could not perform '%s'"
+msgstr "Nu s-a putut efectua „%s”"
+
+#: src/backend_iptables.py:1226
+msgid "Couldn't update rules file for logging"
+msgstr "Nu s-a putut actualiza fișierul cu reguli pentru înregistrarea în jurnal"
+
+#: src/backend_iptables.py:1382
+#, python-format
+msgid "Could not find '%s'. Aborting"
+msgstr "Nu s-a putut găsi „%s”. Se abandonează"
+
+#: src/backend_iptables.py:1394
+#, python-format
+msgid "'%s' already exists. Aborting"
+msgstr "„%s” există deja. Se abandonează"
+
+#: src/backend_iptables.py:1400
+#, python-format
+msgid "Backing up '%(old)s' to '%(new)s'\n"
+msgstr "Se fac copii de rezervă pentru „%(old)s” în „%(new)s”\n"
+
+#: src/backend_iptables.py:1421
+#, python-format
+msgid "WARN: '%s' is world writable"
+msgstr "AVERTISMENT: „%s” poate fi scris de toți utilizatorii"
+
+#: src/backend_iptables.py:1423
+#, python-format
+msgid "WARN: '%s' is world readable"
+msgstr "AVERTISMENT: „%s” poate fi citit de toți utilizatorii"
+
+#: src/frontend.py:93
+#, python-format
+msgid ""
+"\n"
+"Usage: %(progname)s %(command)s\n"
+"\n"
+"%(commands)s:\n"
+" %(enable)-31s enables the firewall\n"
+" %(disable)-31s disables the firewall\n"
+" %(default)-31s set default policy\n"
+" %(logging)-31s set logging to %(level)s\n"
+" %(allow)-31s add allow %(rule)s\n"
+" %(deny)-31s add deny %(rule)s\n"
+" %(reject)-31s add reject %(rule)s\n"
+" %(limit)-31s add limit %(rule)s\n"
+" %(delete)-31s delete %(urule)s\n"
+" %(insert)-31s insert %(urule)s at %(number)s\n"
+" %(route)-31s add route %(urule)s\n"
+" %(route-delete)-31s delete route %(urule)s\n"
+" %(route-insert)-31s insert route %(urule)s at %(number)s\n"
+" %(reload)-31s reload firewall\n"
+" %(reset)-31s reset firewall\n"
+" %(status)-31s show firewall status\n"
+" %(statusnum)-31s show firewall status as numbered list of %(rules)s\n"
+" %(statusverbose)-31s show verbose firewall status\n"
+" %(show)-31s show firewall report\n"
+" %(version)-31s display version information\n"
+"\n"
+"%(appcommands)s:\n"
+" %(applist)-31s list application profiles\n"
+" %(appinfo)-31s show information on %(profile)s\n"
+" %(appupdate)-31s update %(profile)s\n"
+" %(appdefault)-31s set default application policy\n"
+msgstr ""
+"\n"
+"Utilizare: %(progname)s %(command)s\n"
+"\n"
+"%(commands)s:\n"
+" %(enable)-31s activează paravanul de protecție\n"
+" %(disable)-31s dezactivează paravanul de protecție\n"
+" %(default)-31s stabilește politica implicită\n"
+" %(logging)-31s stabilește nivelul jurnalizării la %(level)sn\n"
+" %(allow)-31s adaugă %(rule)s « permite»\n"
+" %(deny)-31s adaugă %(rule)s « refuză»\n"
+" %(reject)-31s adaugă %(rule)s « respinge»\n"
+" %(limit)-31s adaugă %(rule)s «limitei»\n"
+" %(delete)-31s șterge %(urule)s\n"
+" %(insert)-31s inserează %(urule)s la %(number)s\n"
+" %(route)-31s adaugă %(rule)s «direcționare»\n"
+" %(route-delete)-31s șterge %(rule)s «direcționare»\n"
+" %(route-insert)-31s inserează %(rule)s «direcționare» la %(number)s\n"
+" %(reload)-31s reîncarcă paravanul de protecție\n"
+" %(reset)-31s reinițiază paravanul de protecție\n"
+" %(status)-31s afișează starea paravanului de protecție\n"
+" %(statusnum)-31s afișează starea paravanului de protecție ca listă numerotată "
+"de %(rules)s\n"
+" %(statusverbose)-31s afișează starea paravanului de protecție cu informații "
+"detaliate\n"
+" %(show)-31s afișează raportul paravanului de protecție\n"
+" %(version)-31s afișează informațiile despre versiune\n"
+"\n"
+"%(appcommands)s:\n"
+" %(applist)-31s listează profilurile aplicațiilor\n"
+" %(appinfo)-31s afișează informații despre %(profile)s\n"
+" %(appupdate)-31s actualizează %(profile)s\n"
+" %(appdefault)-31s stabilește politica implicită de aplicație\n"
+
+#: src/frontend.py:176
+msgid "n"
+msgstr "n"
+
+#: src/frontend.py:177
+msgid "y"
+msgstr "d"
+
+#: src/frontend.py:178
+msgid "yes"
+msgstr "da"
+
+#: src/frontend.py:223
+msgid "Firewall is active and enabled on system startup"
+msgstr ""
+"Paravanul de protecție este activ și activat pentru lansare la pornirea "
+"sistemului"
+
+#: src/frontend.py:230
+msgid "Firewall stopped and disabled on system startup"
+msgstr ""
+"Paravanul de protecție este oprit și dezactivat pentru lansare la pornirea "
+"sistemului"
+
+#: src/frontend.py:282
+msgid "Could not get listening status"
+msgstr "Nu s-a putut obține starea de ascultare"
+
+#: src/frontend.py:351
+msgid "Added user rules (see 'ufw status' for running firewall):"
+msgstr ""
+"S-au adăugat regulile date de utilizator (consultați „ufw status” pentru a "
+"cunoaște starea actuală a paravanului de protecție):"
+
+# R-GC, scrie:
+# bănuiesc că e vorba de «reguli sau interfețe»,
+# nu văd nimic de genul masculin relaționat cu
+# un paravan de protecție (decît, bineînțeles, el însuși) :)
+#: src/frontend.py:354
+msgid ""
+"\n"
+"(None)"
+msgstr ""
+"\n"
+"(Niciuna)"
+
+#: src/frontend.py:410 src/frontend.py:521 src/frontend.py:534
+#, python-format
+msgid "Invalid IP version '%s'"
+msgstr "Versiunea IP „%s” nu este validă"
+
+#: src/frontend.py:441
+msgid "Invalid position '"
+msgstr "Poziție nevalidă '"
+
+#: src/frontend.py:531
+msgid "IPv6 support not enabled"
+msgstr "Suportul pentru protocolul IPv6 nu este activat"
+
+#: src/frontend.py:542
+msgid "Rule changed after normalization"
+msgstr "Regulă modificată după normalizare"
+
+#: src/frontend.py:566
+#, python-format
+msgid "Could not back out rule '%s'"
+msgstr "Nu s-a putut restabilii definiția anterioară a regulei „%s”"
+
+#: src/frontend.py:570
+msgid ""
+"\n"
+"Error applying application rules."
+msgstr ""
+"\n"
+"Eroare la aplicarea regulilor aplicației."
+
+#: src/frontend.py:572
+msgid " Some rules could not be unapplied."
+msgstr " Unele reguli nu au putut fi anulate."
+
+#: src/frontend.py:574
+msgid " Attempted rules successfully unapplied."
+msgstr " Regulile încercate au fost anulate cu succes."
+
+#: src/frontend.py:585
+#, python-format
+msgid "Could not find rule '%s'"
+msgstr "Nu s-a putut găsi regula „%s”"
+
+#: src/frontend.py:590 src/frontend.py:595
+#, python-format
+msgid "Could not find rule '%d'"
+msgstr "Nu s-a putut găsi regula „%d”"
+
+#: src/frontend.py:611
+#, python-format
+msgid ""
+"Deleting:\n"
+" %(rule)s\n"
+"Proceed with operation (%(yes)s|%(no)s)? "
+msgstr ""
+"Se șterge:\n"
+"  %(rule)s\n"
+"Continuați cu operația (%(yes)s|%(no)s)? "
+
+#: src/frontend.py:643
+msgid "Unsupported default policy"
+msgstr "Politică implicită neacceptată"
+
+#: src/frontend.py:672 src/frontend.py:817
+msgid "Firewall reloaded"
+msgstr "Paravanul de protecție a fost reîncărcat"
+
+#: src/frontend.py:674
+msgid "Firewall not enabled (skipping reload)"
+msgstr "Paravanul de protecție nu este activat (se omite reîncărcarea)"
+
+#: src/frontend.py:691 src/frontend.py:705 src/frontend.py:742
+msgid "Invalid profile name"
+msgstr "Nume de profil nevalid"
+
+#: src/frontend.py:710 src/frontend.py:892
+#, python-format
+msgid "Unsupported action '%s'"
+msgstr "Acțiune neacceptată „%s”"
+
+#: src/frontend.py:729
+msgid "Available applications:"
+msgstr "Aplicații disponibile:"
+
+#: src/frontend.py:750
+#, python-format
+msgid "Could not find profile '%s'"
+msgstr "Nu s-a putut găsi profilul „%s”"
+
+#: src/frontend.py:755
+msgid "Invalid profile"
+msgstr "Profil nevalid"
+
+#: src/frontend.py:758
+#, python-format
+msgid "Profile: %s\n"
+msgstr "Profil: %s\n"
+
+#: src/frontend.py:759
+#, python-format
+msgid "Title: %s\n"
+msgstr "Titlu: %s\n"
+
+#: src/frontend.py:762
+#, python-format
+msgid ""
+"Description: %s\n"
+"\n"
+msgstr ""
+"Descriere: %s\n"
+"\n"
+
+#: src/frontend.py:768
+msgid "Ports:"
+msgstr "Porturi:"
+
+#: src/frontend.py:770
+msgid "Port:"
+msgstr "Port:"
+
+#: src/frontend.py:819
+msgid "Skipped reloading firewall"
+msgstr "S-a omis reîncărcarea paravanului de protecție"
+
+#: src/frontend.py:829
+msgid "Cannot specify 'all' with '--add-new'"
+msgstr "Nu se pot specifica „all” (toate regulile) cu „--add-new”"
+
+#: src/frontend.py:844
+#, python-format
+msgid "Unknown policy '%s'"
+msgstr "Politică necunoscută „%s”"
+
+#: src/frontend.py:901
+#, python-format
+msgid ""
+"Command may disrupt existing ssh connections. Proceed with operation (%(yes)s|"
+"%(no)s)? "
+msgstr ""
+"Comanda poate întrerupe conexiunile SSH existente. Continuați cu operația "
+"(%(yes)s|%(no)s)? "
+
+#: src/frontend.py:914
+#, python-format
+msgid ""
+"Resetting all rules to installed defaults. Proceed with operation (%(yes)s|"
+"%(no)s)? "
+msgstr ""
+"Se restabilesc toate regulile la valorile implicite instalate. Continuați cu "
+"operația (%(yes)s|%(no)s)? "
+
+#: src/frontend.py:918
+#, python-format
+msgid ""
+"Resetting all rules to installed defaults. This may disrupt existing ssh "
+"connections. Proceed with operation (%(yes)s|%(no)s)? "
+msgstr ""
+"Se restabilesc toate regulile la valorile implicite instalate. Acest lucru "
+"poate întrerupe conexiunile SSH existente. Continuați cu operația (%(yes)s|"
+"%(no)s)? "
+
+#: src/applications.py:37
+msgid "Profiles directory does not exist"
+msgstr "Directorul de profiluri nu există"
+
+#: src/applications.py:69
+#, python-format
+msgid "Skipping '%s': couldn't stat"
+msgstr "Se omite „%s”: nu se poate obține starea"
+
+#: src/applications.py:74
+#, python-format
+msgid "Skipping '%s': too big"
+msgstr "Se omite „%s”: este prea mare"
+
+#: src/applications.py:79
+#, python-format
+msgid "Skipping '%s': too many files read already"
+msgstr "Se omite „%s”: prea multe fișiere citite deja"
+
+#: src/applications.py:93
+#, python-format
+msgid "Skipping '%s': couldn't process"
+msgstr "Se omite „%s”: nu s-a putut procesa"
+
+#: src/applications.py:100
+#, python-format
+msgid "Skipping '%s': name too long"
+msgstr "Se omite „%s”: numele este prea lung"
+
+#: src/applications.py:105
+#, python-format
+msgid "Skipping '%s': invalid name"
+msgstr "Se omite „%s”: numele nu este valid"
+
+#: src/applications.py:111
+#, python-format
+msgid "Skipping '%s': also in /etc/services"
+msgstr "Se omite „%s”: de asemenea, în „/etc/services”"
+
+#: src/applications.py:120
+#, python-format
+msgid "Skipping '%s': field too long"
+msgstr "Se omite „%s”: câmpul este prea lung"
+
+#: src/applications.py:125
+#, python-format
+msgid "Skipping '%(value)s': value too long for '%(field)s'"
+msgstr "Se omite „%(value)s”: valoarea este prea X pentru „%(field)s”"
+
+#: src/applications.py:135
+#, python-format
+msgid "Duplicate profile '%s', using last found"
+msgstr "Profil duplicat „%s”, se folosește ultimul găsit"
+
+#: src/applications.py:178
+#, python-format
+msgid "Profile '%(fn)s' missing required field '%(f)s'"
+msgstr "Din profilul „%(fn)s” lipsește câmpul obligatoriu „%(f)s”"
+
+#: src/applications.py:183
+#, python-format
+msgid "Profile '%(fn)s' has empty required field '%(f)s'"
+msgstr "Profilul „%(fn)s” are câmpul obligatoriu gol „%(f)s”"
+
+#: src/applications.py:198
+#, python-format
+msgid "Invalid ports in profile '%s'"
+msgstr "Porturi nevalide în profilul „%s”"
diff -Nru ufw-0.36.1/locales/po/ufw.pot ufw-0.36.2/locales/po/ufw.pot
--- ufw-0.36.1/locales/po/ufw.pot	2021-09-18 20:19:01.000000000 -0500
+++ ufw-0.36.2/locales/po/ufw.pot	2023-05-18 08:07:56.000000000 -0500
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-14 10:02-0600\n"
+"POT-Creation-Date: 2023-05-18 08:07-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -21,601 +21,535 @@
 msgid ": Need at least python 2.6)\n"
 msgstr ""
 
-#: src/ufw:139 src/frontend.py:625 src/frontend.py:927
+#: src/ufw:139 src/frontend.py:636 src/frontend.py:938
 msgid "Aborted"
 msgstr ""
 
-#: src/backend.py:70
-msgid "Couldn't determine iptables version"
-msgstr ""
-
-#: src/backend.py:149
-msgid "problem running sysctl"
-msgstr ""
-
-#: src/backend.py:188
-msgid "Checks disabled"
-msgstr ""
-
-#: src/backend.py:194
-msgid "ERROR: this script should not be SUID"
-msgstr ""
-
-#: src/backend.py:197
-msgid "ERROR: this script should not be SGID"
-msgstr ""
-
-#: src/backend.py:202
-msgid "You need to be root to run this script"
+#: src/applications.py:37
+msgid "Profiles directory does not exist"
 msgstr ""
 
-#: src/backend.py:212
+#: src/applications.py:69
 #, python-format
-msgid "'%s' does not exist"
+msgid "Skipping '%s': couldn't stat"
 msgstr ""
 
-#: src/backend.py:235 src/backend_iptables.py:1416
+#: src/applications.py:74
 #, python-format
-msgid "Couldn't stat '%s'"
+msgid "Skipping '%s': too big"
 msgstr ""
 
-#: src/backend.py:253
+#: src/applications.py:79
 #, python-format
-msgid "uid is %(uid)s but '%(path)s' is owned by %(st_uid)s"
+msgid "Skipping '%s': too many files read already"
 msgstr ""
 
-#: src/backend.py:260
+#: src/applications.py:93
 #, python-format
-msgid "%s is world writable!"
+msgid "Skipping '%s': couldn't process"
 msgstr ""
 
-#: src/backend.py:265
+#: src/applications.py:100
 #, python-format
-msgid "%s is group writable!"
+msgid "Skipping '%s': name too long"
 msgstr ""
 
-#: src/backend.py:281
+#: src/applications.py:105
 #, python-format
-msgid "'%(f)s' file '%(name)s' does not exist"
+msgid "Skipping '%s': invalid name"
 msgstr ""
 
-#: src/backend.py:292 src/backend_iptables.py:690
+#: src/applications.py:111
 #, python-format
-msgid "Couldn't open '%s' for reading"
+msgid "Skipping '%s': also in /etc/services"
 msgstr ""
 
-#: src/backend.py:306
+#: src/applications.py:120
 #, python-format
-msgid "Missing policy for '%s'"
+msgid "Skipping '%s': field too long"
 msgstr ""
 
-#: src/backend.py:310
+#: src/applications.py:125
 #, python-format
-msgid "Invalid policy '%(policy)s' for '%(chain)s'"
-msgstr ""
-
-#: src/backend.py:317
-msgid "Invalid option"
+msgid "Skipping '%(value)s': value too long for '%(field)s'"
 msgstr ""
 
-#: src/backend.py:323 src/backend_iptables.py:790
+#: src/applications.py:135
 #, python-format
-msgid "'%s' is not writable"
+msgid "Duplicate profile '%s', using last found"
 msgstr ""
 
-#: src/backend.py:370 src/backend_iptables.py:94
+#: src/applications.py:178
 #, python-format
-msgid "Unsupported policy '%s'"
+msgid "Profile '%(fn)s' missing required field '%(f)s'"
 msgstr ""
 
-#: src/backend.py:373
+#: src/applications.py:183
 #, python-format
-msgid "Default application policy changed to '%s'"
-msgstr ""
-
-#: src/backend.py:440
-msgid "No rules found for application profile"
+msgid "Profile '%(fn)s' has empty required field '%(f)s'"
 msgstr ""
 
-#: src/backend.py:496
+#: src/applications.py:198
 #, python-format
-msgid "Rules updated for profile '%s'"
+msgid "Invalid ports in profile '%s'"
 msgstr ""
 
-#: src/backend.py:502
-msgid "Couldn't update application rules"
+#: src/backend_iptables.py:82
+msgid "New profiles:"
 msgstr ""
 
-#: src/backend.py:524
+#: src/backend_iptables.py:98 src/backend.py:370
 #, python-format
-msgid "Found multiple matches for '%s'. Please use exact profile name"
+msgid "Unsupported policy '%s'"
 msgstr ""
 
-#: src/backend.py:527
+#: src/backend_iptables.py:103
 #, python-format
-msgid "Could not find a profile matching '%s'"
-msgstr ""
-
-#: src/backend.py:594
-msgid "Logging: "
-msgstr ""
-
-#: src/backend.py:598
-msgid "unknown"
+msgid "Unsupported policy for direction '%s'"
 msgstr ""
 
-#: src/backend.py:610 src/backend_iptables.py:1284
+#: src/backend_iptables.py:163
 #, python-format
-msgid "Invalid log level '%s'"
-msgstr ""
-
-#: src/backend.py:625
-msgid "Logging disabled"
-msgstr ""
-
-#: src/backend.py:627
-msgid "Logging enabled"
+msgid "Default %(direction)s policy changed to '%(policy)s'\n"
 msgstr ""
 
-#: src/common.py:196
-#, python-format
-msgid "Bad port '%s'"
+#: src/backend_iptables.py:165
+msgid "(be sure to update your rules accordingly)"
 msgstr ""
 
-#: src/common.py:252
-#, python-format
-msgid "Unsupported protocol '%s'"
+#: src/backend_iptables.py:172
+msgid "Checking raw iptables\n"
 msgstr ""
 
-#: src/common.py:280
-msgid "Bad source address"
+#: src/backend_iptables.py:173
+msgid "Checking raw ip6tables\n"
 msgstr ""
 
-#: src/common.py:290
-msgid "Bad destination address"
+#: src/backend_iptables.py:266
+msgid "Checking iptables\n"
 msgstr ""
 
-#: src/common.py:309
-msgid "Bad interface type"
+#: src/backend_iptables.py:268
+msgid "Checking ip6tables\n"
 msgstr ""
 
-#: src/common.py:314
-msgid "Bad interface name: reserved character: '!'"
+#: src/backend_iptables.py:271 src/backend_iptables.py:572
+msgid "problem running"
 msgstr ""
 
-#: src/common.py:318
-msgid "Bad interface name: can't use interface aliases"
+#: src/backend_iptables.py:277
+msgid "Status: inactive"
 msgstr ""
 
-#: src/common.py:322
-msgid "Bad interface name: can't use '.' or '..'"
+#: src/backend_iptables.py:447
+msgid "To"
 msgstr ""
 
-#: src/common.py:326
-msgid "Bad interface name: interface name is empty"
+#: src/backend_iptables.py:448
+msgid "From"
 msgstr ""
 
-#: src/common.py:330
-msgid "Bad interface name: interface name too long"
+#: src/backend_iptables.py:449
+msgid "Action"
 msgstr ""
 
-#: src/common.py:335
-msgid "Bad interface name"
+#: src/backend_iptables.py:465 src/backend_iptables.py:469
+msgid "\n"
 msgstr ""
 
-#: src/common.py:349
+#: src/backend_iptables.py:477
 #, python-format
-msgid "Insert position '%s' is not a valid position"
+msgid "Default: %(in)s (incoming), %(out)s (outgoing), %(routed)s (routed)"
 msgstr ""
 
-#: src/common.py:359
+#: src/backend_iptables.py:485
 #, python-format
-msgid "Invalid log type '%s'"
+msgid ""
+"Status: active\n"
+"%(log)s\n"
+"%(pol)s\n"
+"%(app)s%(status)s"
 msgstr ""
 
-#: src/common.py:367
+#: src/backend_iptables.py:489
 #, python-format
-msgid "Unsupported direction '%s'"
+msgid "Status: active%s"
 msgstr ""
 
-#: src/common.py:386
-msgid "Could not normalize source address"
+#: src/backend_iptables.py:494 src/backend_iptables.py:512
+msgid "running ufw-init"
 msgstr ""
 
-#: src/common.py:397
-msgid "Could not normalize destination address"
+#: src/backend_iptables.py:506 src/backend_iptables.py:524
+#, python-format
+msgid ""
+"problem running ufw-init\n"
+"%s"
 msgstr ""
 
-#: src/common.py:463
-msgid "Found exact match"
+#: src/backend_iptables.py:533
+msgid "Could not set LOGLEVEL"
 msgstr ""
 
-#: src/common.py:468
-msgid "Found exact match, excepting comment"
+#: src/backend_iptables.py:539
+msgid "Could not load logging rules"
 msgstr ""
 
-#: src/common.py:472
+#: src/backend_iptables.py:694 src/backend.py:292
 #, python-format
-msgid ""
-"Found non-action/non-logtype/comment match (%(xa)s/%(ya)s/'%(xc)s' %(xl)s/"
-"%(yl)s/'%(yc)s')"
+msgid "Couldn't open '%s' for reading"
 msgstr ""
 
-#: src/common.py:630
+#: src/backend_iptables.py:713
 #, python-format
-msgid "Improper rule syntax ('%s' specified with app rule)"
+msgid "Skipping malformed tuple (bad length): %s"
 msgstr ""
 
-#: src/common.py:637
+#: src/backend_iptables.py:724
 #, python-format
-msgid "Invalid IPv6 address with protocol '%s'"
+msgid "Skipping malformed tuple (iface): %s"
 msgstr ""
 
-#: src/common.py:643 src/util.py:84
+#: src/backend_iptables.py:772
 #, python-format
-msgid "Invalid port with protocol '%s'"
+msgid "Skipping malformed tuple: %s"
 msgstr ""
 
-#: src/parser.py:110
+#: src/backend_iptables.py:794 src/backend.py:323
 #, python-format
-msgid "Cannot insert rule at position '%s'"
-msgstr ""
-
-#: src/parser.py:148
-msgid "Invalid interface clause"
+msgid "'%s' is not writable"
 msgstr ""
 
-#: src/parser.py:174
-msgid "Option 'log' not allowed here"
+#: src/backend_iptables.py:970
+msgid "Adding IPv6 rule failed: IPv6 not enabled"
 msgstr ""
 
-#: src/parser.py:178
-msgid "Option 'log-all' not allowed here"
+#: src/backend_iptables.py:974
+#, python-format
+msgid "Skipping unsupported IPv6 '%s' rule"
 msgstr ""
 
-#: src/parser.py:185
-msgid "Option 'comment' missing required argument"
+#: src/backend_iptables.py:978
+#, python-format
+msgid "Skipping unsupported IPv4 '%s' rule"
 msgstr ""
 
-#: src/parser.py:191
-msgid "Comment may not contain \"'\""
+#: src/backend_iptables.py:981
+msgid "Must specify 'tcp' or 'udp' with multiple ports"
 msgstr ""
 
-#: src/parser.py:233 src/parser.py:359
-msgid "Port ranges must be numeric"
+#: src/backend_iptables.py:993
+msgid "Skipping IPv6 application rule. Need at least iptables 1.4"
 msgstr ""
 
-#: src/parser.py:242 src/util.py:87
-msgid "Bad port"
+#: src/backend_iptables.py:998
+#, python-format
+msgid "Invalid position '%d'"
 msgstr ""
 
-#: src/parser.py:245
-msgid "Wrong number of arguments"
+#: src/backend_iptables.py:1002
+msgid "Cannot specify insert and delete"
 msgstr ""
 
-#: src/parser.py:249
-msgid "Need 'to' or 'from' clause"
+#: src/backend_iptables.py:1063
+msgid "Skipping inserting existing rule"
 msgstr ""
 
-#: src/parser.py:264
-msgid "Improper rule syntax"
+#: src/backend_iptables.py:1074 src/frontend.py:426
+msgid "Could not delete non-existent rule"
 msgstr ""
 
-#: src/parser.py:271
-#, python-format
-msgid "Invalid token '%s'"
+#: src/backend_iptables.py:1079
+msgid "Skipping adding existing rule"
 msgstr ""
 
-#: src/parser.py:283
-msgid "Invalid 'proto' clause"
+#: src/backend_iptables.py:1095
+msgid "Couldn't update rules file"
 msgstr ""
 
-#: src/parser.py:298
-#, python-format
-msgid "Invalid '%s' clause"
+#: src/backend_iptables.py:1100
+msgid "Rules updated"
 msgstr ""
 
-#: src/parser.py:320
-msgid "Invalid 'from' clause"
+#: src/backend_iptables.py:1102
+msgid "Rules updated (v6)"
 msgstr ""
 
-#: src/parser.py:342
-msgid "Invalid 'to' clause"
+#: src/backend_iptables.py:1110
+msgid "Rule inserted"
 msgstr ""
 
-#: src/parser.py:347
-#, python-format
-msgid "Need 'from' or 'to' with '%s'"
+#: src/backend_iptables.py:1112
+msgid "Rule updated"
 msgstr ""
 
-#: src/parser.py:374
-msgid "Invalid 'port' clause"
+#: src/backend_iptables.py:1122 src/backend_iptables.py:1139
+msgid " (skipped reloading firewall)"
 msgstr ""
 
-#: src/parser.py:383
-msgid "Mixed IP versions for 'from' and 'to'"
+#: src/backend_iptables.py:1125
+msgid "Rule deleted"
 msgstr ""
 
-#: src/parser.py:400 src/parser.py:410 src/parser.py:419
-msgid "Could not find protocol"
+#: src/backend_iptables.py:1142
+msgid "Rule added"
 msgstr ""
 
-#: src/parser.py:426
-msgid "Protocol mismatch (from/to)"
+#: src/backend_iptables.py:1159 src/backend_iptables.py:1250
+msgid "Could not update running firewall"
 msgstr ""
 
-#: src/parser.py:433
+#: src/backend_iptables.py:1214
 #, python-format
-msgid "Protocol mismatch with specified protocol %s"
-msgstr ""
-
-#: src/parser.py:552
-msgid "'route delete NUM' unsupported. Use 'delete NUM' instead."
+msgid "Could not perform '%s'"
 msgstr ""
 
-#: src/parser.py:585
-msgid "Invalid interface clause for route rule"
+#: src/backend_iptables.py:1241
+msgid "Couldn't update rules file for logging"
 msgstr ""
 
-#: src/parser.py:884
+#: src/backend_iptables.py:1299 src/backend.py:610
 #, python-format
-msgid "Command '%s' already exists"
-msgstr ""
-
-#: src/util.py:446
-msgid "Couldn't find pid (is /proc mounted?)"
+msgid "Invalid log level '%s'"
 msgstr ""
 
-#: src/util.py:450
+#: src/backend_iptables.py:1397
 #, python-format
-msgid "Couldn't find parent pid for '%s'"
+msgid "Could not find '%s'. Aborting"
 msgstr ""
 
-#: src/util.py:460
+#: src/backend_iptables.py:1409
 #, python-format
-msgid "Couldn't find '%s'"
+msgid "'%s' already exists. Aborting"
 msgstr ""
 
-#: src/util.py:466
+#: src/backend_iptables.py:1415
 #, python-format
-msgid "Could not find executable for '%s'"
+msgid "Backing up '%(old)s' to '%(new)s'\n"
 msgstr ""
 
-#: src/util.py:1026
+#: src/backend_iptables.py:1431 src/backend.py:235
 #, python-format
-msgid "Could not get statistics for '%s'"
-msgstr ""
-
-#: src/backend_iptables.py:78
-msgid "New profiles:"
+msgid "Couldn't stat '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:99
+#: src/backend_iptables.py:1436
 #, python-format
-msgid "Unsupported policy for direction '%s'"
+msgid "WARN: '%s' is world writable"
 msgstr ""
 
-#: src/backend_iptables.py:159
+#: src/backend_iptables.py:1438
 #, python-format
-msgid "Default %(direction)s policy changed to '%(policy)s'\n"
-msgstr ""
-
-#: src/backend_iptables.py:161
-msgid "(be sure to update your rules accordingly)"
+msgid "WARN: '%s' is world readable"
 msgstr ""
 
-#: src/backend_iptables.py:168
-msgid "Checking raw iptables\n"
+#: src/backend.py:70
+msgid "Couldn't determine iptables version"
 msgstr ""
 
-#: src/backend_iptables.py:169
-msgid "Checking raw ip6tables\n"
+#: src/backend.py:149
+msgid "problem running sysctl"
 msgstr ""
 
-#: src/backend_iptables.py:262
-msgid "Checking iptables\n"
+#: src/backend.py:188
+msgid "Checks disabled"
 msgstr ""
 
-#: src/backend_iptables.py:264
-msgid "Checking ip6tables\n"
+#: src/backend.py:194
+msgid "ERROR: this script should not be SUID"
 msgstr ""
 
-#: src/backend_iptables.py:267 src/backend_iptables.py:568
-msgid "problem running"
+#: src/backend.py:197
+msgid "ERROR: this script should not be SGID"
 msgstr ""
 
-#: src/backend_iptables.py:273
-msgid "Status: inactive"
+#: src/backend.py:202
+msgid "You need to be root to run this script"
 msgstr ""
 
-#: src/backend_iptables.py:443
-msgid "To"
+#: src/backend.py:212
+#, python-format
+msgid "'%s' does not exist"
 msgstr ""
 
-#: src/backend_iptables.py:444
-msgid "From"
+#: src/backend.py:253
+#, python-format
+msgid "uid is %(uid)s but '%(path)s' is owned by %(st_uid)s"
 msgstr ""
 
-#: src/backend_iptables.py:445
-msgid "Action"
+#: src/backend.py:260
+#, python-format
+msgid "%s is world writable!"
 msgstr ""
 
-#: src/backend_iptables.py:461 src/backend_iptables.py:465
-msgid "\n"
+#: src/backend.py:265
+#, python-format
+msgid "%s is group writable!"
 msgstr ""
 
-#: src/backend_iptables.py:473
+#: src/backend.py:281
 #, python-format
-msgid "Default: %(in)s (incoming), %(out)s (outgoing), %(routed)s (routed)"
+msgid "'%(f)s' file '%(name)s' does not exist"
 msgstr ""
 
-#: src/backend_iptables.py:481
+#: src/backend.py:306
 #, python-format
-msgid ""
-"Status: active\n"
-"%(log)s\n"
-"%(pol)s\n"
-"%(app)s%(status)s"
+msgid "Missing policy for '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:485
+#: src/backend.py:310
 #, python-format
-msgid "Status: active%s"
+msgid "Invalid policy '%(policy)s' for '%(chain)s'"
 msgstr ""
 
-#: src/backend_iptables.py:490 src/backend_iptables.py:508
-msgid "running ufw-init"
+#: src/backend.py:317
+msgid "Invalid option"
 msgstr ""
 
-#: src/backend_iptables.py:502 src/backend_iptables.py:520
+#: src/backend.py:373
 #, python-format
-msgid ""
-"problem running ufw-init\n"
-"%s"
-msgstr ""
-
-#: src/backend_iptables.py:529
-msgid "Could not set LOGLEVEL"
+msgid "Default application policy changed to '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:535
-msgid "Could not load logging rules"
+#: src/backend.py:440
+msgid "No rules found for application profile"
 msgstr ""
 
-#: src/backend_iptables.py:709
+#: src/backend.py:496
 #, python-format
-msgid "Skipping malformed tuple (bad length): %s"
+msgid "Rules updated for profile '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:720
-#, python-format
-msgid "Skipping malformed tuple (iface): %s"
+#: src/backend.py:502
+msgid "Couldn't update application rules"
 msgstr ""
 
-#: src/backend_iptables.py:768
+#: src/backend.py:524
 #, python-format
-msgid "Skipping malformed tuple: %s"
+msgid "Found multiple matches for '%s'. Please use exact profile name"
 msgstr ""
 
-#: src/backend_iptables.py:966
-msgid "Adding IPv6 rule failed: IPv6 not enabled"
+#: src/backend.py:527
+#, python-format
+msgid "Could not find a profile matching '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:970
-#, python-format
-msgid "Skipping unsupported IPv6 '%s' rule"
+#: src/backend.py:594
+msgid "Logging: "
 msgstr ""
 
-#: src/backend_iptables.py:974
-#, python-format
-msgid "Skipping unsupported IPv4 '%s' rule"
+#: src/backend.py:598
+msgid "unknown"
 msgstr ""
 
-#: src/backend_iptables.py:977
-msgid "Must specify 'tcp' or 'udp' with multiple ports"
+#: src/backend.py:625
+msgid "Logging disabled"
 msgstr ""
 
-#: src/backend_iptables.py:989
-msgid "Skipping IPv6 application rule. Need at least iptables 1.4"
+#: src/backend.py:627
+msgid "Logging enabled"
 msgstr ""
 
-#: src/backend_iptables.py:994
+#: src/common.py:196
 #, python-format
-msgid "Invalid position '%d'"
+msgid "Bad port '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:998
-msgid "Cannot specify insert and delete"
+#: src/common.py:252
+#, python-format
+msgid "Unsupported protocol '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:1001
-#, python-format
-msgid "Cannot insert rule at position '%d'"
+#: src/common.py:280
+msgid "Bad source address"
 msgstr ""
 
-#: src/backend_iptables.py:1062
-msgid "Skipping inserting existing rule"
+#: src/common.py:290
+msgid "Bad destination address"
 msgstr ""
 
-#: src/backend_iptables.py:1073 src/frontend.py:415
-msgid "Could not delete non-existent rule"
+#: src/common.py:309
+msgid "Bad interface type"
 msgstr ""
 
-#: src/backend_iptables.py:1078
-msgid "Skipping adding existing rule"
+#: src/common.py:314
+msgid "Bad interface name: reserved character: '!'"
 msgstr ""
 
-#: src/backend_iptables.py:1094
-msgid "Couldn't update rules file"
+#: src/common.py:318
+msgid "Bad interface name: can't use interface aliases"
 msgstr ""
 
-#: src/backend_iptables.py:1099
-msgid "Rules updated"
+#: src/common.py:322
+msgid "Bad interface name: can't use '.' or '..'"
 msgstr ""
 
-#: src/backend_iptables.py:1101
-msgid "Rules updated (v6)"
+#: src/common.py:326
+msgid "Bad interface name: interface name is empty"
 msgstr ""
 
-#: src/backend_iptables.py:1109
-msgid "Rule inserted"
+#: src/common.py:330
+msgid "Bad interface name: interface name too long"
 msgstr ""
 
-#: src/backend_iptables.py:1111
-msgid "Rule updated"
+#: src/common.py:335
+msgid "Bad interface name"
 msgstr ""
 
-#: src/backend_iptables.py:1121
-msgid " (skipped reloading firewall)"
+#: src/common.py:349
+#, python-format
+msgid "Insert position '%s' is not a valid position"
 msgstr ""
 
-#: src/backend_iptables.py:1124
-msgid "Rule deleted"
+#: src/common.py:359
+#, python-format
+msgid "Invalid log type '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:1127
-msgid "Rule added"
+#: src/common.py:367
+#, python-format
+msgid "Unsupported direction '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:1144 src/backend_iptables.py:1235
-msgid "Could not update running firewall"
+#: src/common.py:386
+msgid "Could not normalize source address"
 msgstr ""
 
-#: src/backend_iptables.py:1199
-#, python-format
-msgid "Could not perform '%s'"
+#: src/common.py:397
+msgid "Could not normalize destination address"
 msgstr ""
 
-#: src/backend_iptables.py:1226
-msgid "Couldn't update rules file for logging"
+#: src/common.py:463
+msgid "Found exact match"
 msgstr ""
 
-#: src/backend_iptables.py:1382
-#, python-format
-msgid "Could not find '%s'. Aborting"
+#: src/common.py:468
+msgid "Found exact match, excepting comment"
 msgstr ""
 
-#: src/backend_iptables.py:1394
+#: src/common.py:472
 #, python-format
-msgid "'%s' already exists. Aborting"
+msgid ""
+"Found non-action/non-logtype/comment match (%(xa)s/%(ya)s/'%(xc)s' %(xl)s/"
+"%(yl)s/'%(yc)s')"
 msgstr ""
 
-#: src/backend_iptables.py:1400
+#: src/common.py:635
 #, python-format
-msgid "Backing up '%(old)s' to '%(new)s'\n"
+msgid "Improper rule syntax ('%s' specified with app rule)"
 msgstr ""
 
-#: src/backend_iptables.py:1421
+#: src/common.py:642
 #, python-format
-msgid "WARN: '%s' is world writable"
+msgid "Invalid IPv6 address with protocol '%s'"
 msgstr ""
 
-#: src/backend_iptables.py:1423
+#: src/common.py:648 src/util.py:84
 #, python-format
-msgid "WARN: '%s' is world readable"
+msgid "Invalid port with protocol '%s'"
 msgstr ""
 
-#: src/frontend.py:93
+#: src/frontend.py:103
 #, python-format
 msgid ""
 "\n"
@@ -632,6 +566,7 @@
 " %(limit)-31s add limit %(rule)s\n"
 " %(delete)-31s delete %(urule)s\n"
 " %(insert)-31s insert %(urule)s at %(number)s\n"
+" %(prepend)-31s prepend %(urule)s\n"
 " %(route)-31s add route %(urule)s\n"
 " %(route-delete)-31s delete route %(urule)s\n"
 " %(route-insert)-31s insert route %(urule)s at %(number)s\n"
@@ -650,87 +585,87 @@
 " %(appdefault)-31s set default application policy\n"
 msgstr ""
 
-#: src/frontend.py:176
+#: src/frontend.py:187
 msgid "n"
 msgstr ""
 
-#: src/frontend.py:177
+#: src/frontend.py:188
 msgid "y"
 msgstr ""
 
-#: src/frontend.py:178
+#: src/frontend.py:189
 msgid "yes"
 msgstr ""
 
-#: src/frontend.py:223
+#: src/frontend.py:234
 msgid "Firewall is active and enabled on system startup"
 msgstr ""
 
-#: src/frontend.py:230
+#: src/frontend.py:241
 msgid "Firewall stopped and disabled on system startup"
 msgstr ""
 
-#: src/frontend.py:282
+#: src/frontend.py:293
 msgid "Could not get listening status"
 msgstr ""
 
-#: src/frontend.py:351
+#: src/frontend.py:362
 msgid "Added user rules (see 'ufw status' for running firewall):"
 msgstr ""
 
-#: src/frontend.py:354
+#: src/frontend.py:365
 msgid ""
 "\n"
 "(None)"
 msgstr ""
 
-#: src/frontend.py:410 src/frontend.py:521 src/frontend.py:534
+#: src/frontend.py:421 src/frontend.py:532 src/frontend.py:545
 #, python-format
 msgid "Invalid IP version '%s'"
 msgstr ""
 
-#: src/frontend.py:441
+#: src/frontend.py:452
 msgid "Invalid position '"
 msgstr ""
 
-#: src/frontend.py:531
+#: src/frontend.py:542
 msgid "IPv6 support not enabled"
 msgstr ""
 
-#: src/frontend.py:542
+#: src/frontend.py:553
 msgid "Rule changed after normalization"
 msgstr ""
 
-#: src/frontend.py:566
+#: src/frontend.py:577
 #, python-format
 msgid "Could not back out rule '%s'"
 msgstr ""
 
-#: src/frontend.py:570
+#: src/frontend.py:581
 msgid ""
 "\n"
 "Error applying application rules."
 msgstr ""
 
-#: src/frontend.py:572
+#: src/frontend.py:583
 msgid " Some rules could not be unapplied."
 msgstr ""
 
-#: src/frontend.py:574
+#: src/frontend.py:585
 msgid " Attempted rules successfully unapplied."
 msgstr ""
 
-#: src/frontend.py:585
+#: src/frontend.py:596
 #, python-format
 msgid "Could not find rule '%s'"
 msgstr ""
 
-#: src/frontend.py:590 src/frontend.py:595
+#: src/frontend.py:601 src/frontend.py:606
 #, python-format
 msgid "Could not find rule '%d'"
 msgstr ""
 
-#: src/frontend.py:611
+#: src/frontend.py:622
 #, python-format
 msgid ""
 "Deleting:\n"
@@ -738,164 +673,225 @@
 "Proceed with operation (%(yes)s|%(no)s)? "
 msgstr ""
 
-#: src/frontend.py:643
+#: src/frontend.py:654
 msgid "Unsupported default policy"
 msgstr ""
 
-#: src/frontend.py:672 src/frontend.py:817
+#: src/frontend.py:683 src/frontend.py:828
 msgid "Firewall reloaded"
 msgstr ""
 
-#: src/frontend.py:674
+#: src/frontend.py:685
 msgid "Firewall not enabled (skipping reload)"
 msgstr ""
 
-#: src/frontend.py:691 src/frontend.py:705 src/frontend.py:742
+#: src/frontend.py:702 src/frontend.py:716 src/frontend.py:753
 msgid "Invalid profile name"
 msgstr ""
 
-#: src/frontend.py:710 src/frontend.py:892
+#: src/frontend.py:721 src/frontend.py:903
 #, python-format
 msgid "Unsupported action '%s'"
 msgstr ""
 
-#: src/frontend.py:729
+#: src/frontend.py:740
 msgid "Available applications:"
 msgstr ""
 
-#: src/frontend.py:750
+#: src/frontend.py:761
 #, python-format
 msgid "Could not find profile '%s'"
 msgstr ""
 
-#: src/frontend.py:755
+#: src/frontend.py:766
 msgid "Invalid profile"
 msgstr ""
 
-#: src/frontend.py:758
+#: src/frontend.py:769
 #, python-format
 msgid "Profile: %s\n"
 msgstr ""
 
-#: src/frontend.py:759
+#: src/frontend.py:770
 #, python-format
 msgid "Title: %s\n"
 msgstr ""
 
-#: src/frontend.py:762
+#: src/frontend.py:773
 #, python-format
 msgid ""
 "Description: %s\n"
 "\n"
 msgstr ""
 
-#: src/frontend.py:768
+#: src/frontend.py:779
 msgid "Ports:"
 msgstr ""
 
-#: src/frontend.py:770
+#: src/frontend.py:781
 msgid "Port:"
 msgstr ""
 
-#: src/frontend.py:819
+#: src/frontend.py:830
 msgid "Skipped reloading firewall"
 msgstr ""
 
-#: src/frontend.py:829
+#: src/frontend.py:840
 msgid "Cannot specify 'all' with '--add-new'"
 msgstr ""
 
-#: src/frontend.py:844
+#: src/frontend.py:855
 #, python-format
 msgid "Unknown policy '%s'"
 msgstr ""
 
-#: src/frontend.py:901
+#: src/frontend.py:912
 #, python-format
 msgid ""
 "Command may disrupt existing ssh connections. Proceed with operation "
 "(%(yes)s|%(no)s)? "
 msgstr ""
 
-#: src/frontend.py:914
+#: src/frontend.py:925
 #, python-format
 msgid ""
 "Resetting all rules to installed defaults. Proceed with operation (%(yes)s|"
 "%(no)s)? "
 msgstr ""
 
-#: src/frontend.py:918
+#: src/frontend.py:929
 #, python-format
 msgid ""
 "Resetting all rules to installed defaults. This may disrupt existing ssh "
 "connections. Proceed with operation (%(yes)s|%(no)s)? "
 msgstr ""
 
-#: src/applications.py:37
-msgid "Profiles directory does not exist"
+#: src/parser.py:110
+#, python-format
+msgid "Cannot insert rule at position '%s'"
 msgstr ""
 
-#: src/applications.py:69
-#, python-format
-msgid "Skipping '%s': couldn't stat"
+#: src/parser.py:148
+msgid "Invalid interface clause"
 msgstr ""
 
-#: src/applications.py:74
-#, python-format
-msgid "Skipping '%s': too big"
+#: src/parser.py:174
+msgid "Option 'log' not allowed here"
 msgstr ""
 
-#: src/applications.py:79
-#, python-format
-msgid "Skipping '%s': too many files read already"
+#: src/parser.py:178
+msgid "Option 'log-all' not allowed here"
 msgstr ""
 
-#: src/applications.py:93
-#, python-format
-msgid "Skipping '%s': couldn't process"
+#: src/parser.py:185
+msgid "Option 'comment' missing required argument"
 msgstr ""
 
-#: src/applications.py:100
+#: src/parser.py:191
+msgid "Comment may not contain \"'\""
+msgstr ""
+
+#: src/parser.py:233 src/parser.py:359
+msgid "Port ranges must be numeric"
+msgstr ""
+
+#: src/parser.py:242 src/util.py:87
+msgid "Bad port"
+msgstr ""
+
+#: src/parser.py:245
+msgid "Wrong number of arguments"
+msgstr ""
+
+#: src/parser.py:249
+msgid "Need 'to' or 'from' clause"
+msgstr ""
+
+#: src/parser.py:264
+msgid "Improper rule syntax"
+msgstr ""
+
+#: src/parser.py:271
 #, python-format
-msgid "Skipping '%s': name too long"
+msgid "Invalid token '%s'"
 msgstr ""
 
-#: src/applications.py:105
+#: src/parser.py:283
+msgid "Invalid 'proto' clause"
+msgstr ""
+
+#: src/parser.py:298
 #, python-format
-msgid "Skipping '%s': invalid name"
+msgid "Invalid '%s' clause"
 msgstr ""
 
-#: src/applications.py:111
+#: src/parser.py:320
+msgid "Invalid 'from' clause"
+msgstr ""
+
+#: src/parser.py:342
+msgid "Invalid 'to' clause"
+msgstr ""
+
+#: src/parser.py:347
 #, python-format
-msgid "Skipping '%s': also in /etc/services"
+msgid "Need 'from' or 'to' with '%s'"
 msgstr ""
 
-#: src/applications.py:120
+#: src/parser.py:374
+msgid "Invalid 'port' clause"
+msgstr ""
+
+#: src/parser.py:383
+msgid "Mixed IP versions for 'from' and 'to'"
+msgstr ""
+
+#: src/parser.py:400 src/parser.py:410 src/parser.py:419
+msgid "Could not find protocol"
+msgstr ""
+
+#: src/parser.py:426
+msgid "Protocol mismatch (from/to)"
+msgstr ""
+
+#: src/parser.py:433
 #, python-format
-msgid "Skipping '%s': field too long"
+msgid "Protocol mismatch with specified protocol %s"
 msgstr ""
 
-#: src/applications.py:125
+#: src/parser.py:552
+msgid "'route delete NUM' unsupported. Use 'delete NUM' instead."
+msgstr ""
+
+#: src/parser.py:585
+msgid "Invalid interface clause for route rule"
+msgstr ""
+
+#: src/parser.py:884
 #, python-format
-msgid "Skipping '%(value)s': value too long for '%(field)s'"
+msgid "Command '%s' already exists"
 msgstr ""
 
-#: src/applications.py:135
+#: src/util.py:431
+msgid "Couldn't find pid (is /proc mounted?)"
+msgstr ""
+
+#: src/util.py:435
 #, python-format
-msgid "Duplicate profile '%s', using last found"
+msgid "Couldn't find parent pid for '%s'"
 msgstr ""
 
-#: src/applications.py:178
+#: src/util.py:445
 #, python-format
-msgid "Profile '%(fn)s' missing required field '%(f)s'"
+msgid "Couldn't find '%s'"
 msgstr ""
 
-#: src/applications.py:183
+#: src/util.py:451
 #, python-format
-msgid "Profile '%(fn)s' has empty required field '%(f)s'"
+msgid "Could not find executable for '%s'"
 msgstr ""
 
-#: src/applications.py:198
+#: src/util.py:1037
 #, python-format
-msgid "Invalid ports in profile '%s'"
+msgid "Could not get statistics for '%s'"
 msgstr ""
diff -Nru ufw-0.36.1/setup.py ufw-0.36.2/setup.py
--- ufw-0.36.1/setup.py	2021-09-18 20:19:01.000000000 -0500
+++ ufw-0.36.2/setup.py	2023-05-18 08:07:39.000000000 -0500
@@ -34,7 +34,7 @@
 import shutil
 import subprocess
 
-ufw_version = '0.36.1'
+ufw_version = '0.36.2'
 
 def cmd(command):
     '''Try to execute the given command.'''
diff -Nru ufw-0.36.1/snapcraft.yaml ufw-0.36.2/snapcraft.yaml
--- ufw-0.36.1/snapcraft.yaml	2021-09-18 20:19:01.000000000 -0500
+++ ufw-0.36.2/snapcraft.yaml	2023-05-18 08:07:39.000000000 -0500
@@ -1,5 +1,5 @@
 name: ufw
-version: 0.36.1
+version: 0.36.2
 summary: ufw (Uncomplicated Firewall)
 description: ufw as a snap
 confinement: strict
diff -Nru ufw-0.36.1/src/backend_iptables.py ufw-0.36.2/src/backend_iptables.py
--- ufw-0.36.1/src/backend_iptables.py	2021-09-18 20:19:01.000000000 -0500
+++ ufw-0.36.2/src/backend_iptables.py	2023-05-18 08:07:39.000000000 -0500
@@ -1001,9 +1001,6 @@
         if position > 0 and rule.remove:
             err_msg = _("Cannot specify insert and delete")
             raise UFWError(err_msg)
-        if position > len(rules):
-            err_msg = _("Cannot insert rule at position '%d'") % position
-            raise UFWError(err_msg)
 
         # First construct the new rules list
         try:
diff -Nru ufw-0.36.1/src/backend.py ufw-0.36.2/src/backend.py
--- ufw-0.36.1/src/backend.py	2021-09-18 20:19:01.000000000 -0500
+++ ufw-0.36.2/src/backend.py	2023-05-18 08:07:39.000000000 -0500
@@ -1,6 +1,6 @@
 '''backend.py: interface for ufw backends'''
 #
-# Copyright 2008-2018 Canonical Ltd.
+# Copyright 2008-2023 Canonical Ltd.
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License version 3,
@@ -628,7 +628,15 @@
 
     def get_rules(self):
         '''Return list of all rules'''
-        return self.rules + self.rules6
+        return self.get_rules_ipv4() + self.get_rules_ipv6()
+
+    def get_rules_ipv4(self):
+        '''Return list of IPv4 rules'''
+        return self.rules
+
+    def get_rules_ipv6(self):
+        '''Return list of IPv6 rules'''
+        return self.rules6
 
     def get_rules_count(self, v6):
         '''Return number of ufw rules (not iptables rules)'''
diff -Nru ufw-0.36.1/src/frontend.py ufw-0.36.2/src/frontend.py
--- ufw-0.36.1/src/frontend.py	2021-09-18 20:19:01.000000000 -0500
+++ ufw-0.36.2/src/frontend.py	2023-05-18 08:07:39.000000000 -0500
@@ -1,6 +1,6 @@
 '''frontend.py: frontend interface for ufw'''
 #
-# Copyright 2008-2018 Canonical Ltd.
+# Copyright 2008-2023 Canonical Ltd.
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License version 3,
@@ -31,8 +31,17 @@
     p = ufw.parser.UFWParser()
 
     # Basic commands
-    for i in ['enable', 'disable', 'help', '--help', 'version', '--version', \
-              'reload', 'reset' ]:
+    for i in [
+        "enable",
+        "disable",
+        "help",
+        "--help",
+        "-h",
+        "version",
+        "--version",
+        "reload",
+        "reset",
+    ]:
         p.register_command(ufw.parser.UFWCommandBasic(i))
 
     # Application commands
@@ -74,8 +83,9 @@
            argv[idx].lower() in rule_commands:
             argv.insert(idx, 'rule')
 
-    if len(argv) < 2 or ('--dry-run' in argv and len(argv) < 3):
-        error("not enough args") # pragma: no cover
+    if len(argv) < 2 or ("--dry-run" in argv and len(argv) < 3):
+        error("not enough args", do_exit=False)  # pragma: no cover
+        raise ValueError()
 
     try:
         pr = p.parse_command(argv[1:])
diff -Nru ufw-0.36.1/src/ufw ufw-0.36.2/src/ufw
--- ufw-0.36.1/src/ufw	2021-09-18 20:19:01.000000000 -0500
+++ ufw-0.36.2/src/ufw	2023-05-18 08:07:39.000000000 -0500
@@ -2,7 +2,7 @@
 #
 # ufw: front-end for Linux firewalling (cli)
 #
-# Copyright 2008-2018 Canonical Ltd.
+# Copyright 2008-2023 Canonical Ltd.
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License version 3,
@@ -103,12 +103,12 @@
     except Exception:
         raise
 
-    if pr.action == "help" or pr.action == "--help":
+    if pr.action == "help" or pr.action == "--help" or pr.action == "-h":
         msg(ufw.frontend.get_command_help())
         sys.exit(0)
     elif pr.action == "version" or pr.action == "--version":
         msg(ufw.common.programName + " " + version)
-        msg("Copyright 2008-2018 Canonical Ltd.")
+        msg("Copyright 2008-2023 Canonical Ltd.")
         sys.exit(0)
 
     try:
diff -Nru ufw-0.36.1/src/ufw-init-functions ufw-0.36.2/src/ufw-init-functions
--- ufw-0.36.1/src/ufw-init-functions	2021-09-18 17:00:21.000000000 -0500
+++ ufw-0.36.2/src/ufw-init-functions	2023-05-16 09:51:25.000000000 -0500
@@ -168,29 +168,6 @@
             AFTER_RULES="$RULES_PATH/after${type}.rules"
             USER_RULES="$USER_PATH/user${type}.rules"
 
-            # set the default policy
-            input_pol="$DEFAULT_INPUT_POLICY"
-            if [ "$DEFAULT_INPUT_POLICY" = "REJECT" ]; then
-                input_pol="DROP"
-            fi
-
-            output_pol="$DEFAULT_OUTPUT_POLICY"
-            if [ "$DEFAULT_OUTPUT_POLICY" = "REJECT" ]; then
-                output_pol="DROP"
-            fi
-
-            forward_pol="$DEFAULT_FORWARD_POLICY"
-            if [ "$DEFAULT_FORWARD_POLICY" = "REJECT" ]; then
-                forward_pol="DROP"
-            fi
-
-            printf "*filter\n"\
-"# builtin chains\n"\
-":INPUT %s [0:0]\n"\
-":FORWARD %s [0:0]\n"\
-":OUTPUT %s [0:0]\n"\
-"COMMIT\n" $input_pol $forward_pol $output_pol | $exe-restore -n || error="yes"
-
             # flush the chains (if they exist)
             if $exe -L ufw${type}-before-logging-input -n >/dev/null 2>&1 ; then
                 delete_chains $type || error="yes"
@@ -378,6 +355,32 @@
                 out="${out}\nCouldn't find '$USER_RULES'"
                 error="yes"
             fi
+
+            # set the default policy (do this after loading rules so not to
+            # break network rootfs w/ INPUT DROP during ufw init. LP: 1946804)
+            input_pol="$DEFAULT_INPUT_POLICY"
+            if [ "$DEFAULT_INPUT_POLICY" = "REJECT" ]; then
+                input_pol="DROP"
+            fi
+
+            output_pol="$DEFAULT_OUTPUT_POLICY"
+            if [ "$DEFAULT_OUTPUT_POLICY" = "REJECT" ]; then
+                output_pol="DROP"
+            fi
+
+            forward_pol="$DEFAULT_FORWARD_POLICY"
+            if [ "$DEFAULT_FORWARD_POLICY" = "REJECT" ]; then
+                forward_pol="DROP"
+            fi
+
+            # Since we're setting the default policy last, '-n/--noflush' is
+            # important here so we don't undo what we've loaded so far.
+            printf "*filter\n"\
+"# builtin chains\n"\
+":INPUT %s [0:0]\n"\
+":FORWARD %s [0:0]\n"\
+":OUTPUT %s [0:0]\n"\
+"COMMIT\n" $input_pol $forward_pol $output_pol | $exe-restore -n || error="yes"
         done
 
         if [ ! -z "$IPT_SYSCTL" ] && [ -s "$IPT_SYSCTL" ]; then
diff -Nru ufw-0.36.1/src/util.py ufw-0.36.2/src/util.py
--- ufw-0.36.1/src/util.py	2021-09-18 20:19:01.000000000 -0500
+++ ufw-0.36.2/src/util.py	2023-05-18 08:07:39.000000000 -0500
@@ -1,6 +1,6 @@
 '''util.py: utility functions for ufw'''
 #
-# Copyright 2008-2018 Canonical Ltd.
+# Copyright 2008-2023 Canonical Ltd.
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License version 3,
@@ -38,9 +38,9 @@
 
 # We support different protocols these days and only come combinations are
 # valid
-supported_protocols = [ 'tcp', 'udp', 'ipv6', 'esp', 'ah', 'igmp', 'gre' ]
-portless_protocols = [ 'ipv6', 'esp', 'ah', 'igmp', 'gre' ]
-ipv4_only_protocols = [ 'ipv6', 'igmp' ]
+supported_protocols = ["tcp", "udp", "ipv6", "esp", "ah", "igmp", "gre", "vrrp"]
+portless_protocols = ["ipv6", "esp", "ah", "igmp", "gre", "vrrp"]
+ipv4_only_protocols = ["ipv6", "igmp"]
 
 
 def get_services_proto(port):
@@ -416,7 +416,9 @@
     # LP: #1101304
     # 9983 (cmd) S 923 ...
     # 9983 (cmd with spaces) S 923 ...
-    ppid = open(name).readlines()[0].split(')')[1].split()[1]
+    # LP: #2015645
+    # 229 (cmd(withparen)) S 228 ...
+    ppid = open(name).readlines()[0].rsplit(")", 1)[1].split()[1]
 
     return int(ppid)
 
@@ -1083,8 +1085,16 @@
 def hex_decode(h):
     '''Take a hex string and convert it to a string'''
     if sys.version_info[0] < 3:
-        return h.decode(encoding='hex').decode('utf-8')
-    return binascii.unhexlify(h).decode('utf-8')
+        return h.decode(encoding="hex").decode("utf-8")
+    # unhexlify requires an even length string, which should normally happen
+    # since hex_encode() will create a string and decode to ascii, which has 2
+    # bytes per character. If we happen to get an odd length string, instead of
+    # tracing back, truncate it by one character and move on. This works
+    # reasonably well in some cases, but might result in a UnicodeDecodeError,
+    # so use backslashreplace in that case.
+    return binascii.unhexlify("%s" % (h[:-1] if len(h) % 2 else h)).decode(
+        "utf-8", "backslashreplace"
+    )
 
 
 def create_lock(lockfile='/run/ufw.lock', dryrun=False):
diff -Nru ufw-0.36.1/tests/bugs/misc/result ufw-0.36.2/tests/bugs/misc/result
--- ufw-0.36.1/tests/bugs/misc/result	2018-12-14 12:25:55.000000000 -0600
+++ ufw-0.36.2/tests/bugs/misc/result	2023-05-16 09:51:25.000000000 -0500
@@ -163,6 +163,38 @@
 29: --dry-run
 ERROR: not enough args
 
+Usage: ufw COMMAND
+
+Commands:
+ enable                          enables the firewall
+ disable                         disables the firewall
+ default ARG                     set default policy
+ logging LEVEL                   set logging to LEVEL
+ allow ARGS                      add allow rule
+ deny ARGS                       add deny rule
+ reject ARGS                     add reject rule
+ limit ARGS                      add limit rule
+ delete RULE|NUM                 delete RULE
+ insert NUM RULE                 insert RULE at NUM
+ prepend RULE                    prepend RULE
+ route RULE                      add route RULE
+ route delete RULE|NUM           delete route RULE
+ route insert NUM RULE           insert route RULE at NUM
+ reload                          reload firewall
+ reset                           reset firewall
+ status                          show firewall status
+ status numbered                 show firewall status as numbered list of RULES
+ status verbose                  show verbose firewall status
+ show ARG                        show firewall report
+ version                         display version information
+
+Application profile commands:
+ app list                        list application profiles
+ app info PROFILE                show information on PROFILE
+ app update PROFILE              update PROFILE
+ app default ARG                 set default application policy
+
+
 
 Bug #787955
 30: --dry-run status
diff -Nru ufw-0.36.1/tests/check-requirements ufw-0.36.2/tests/check-requirements
--- ufw-0.36.1/tests/check-requirements	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/tests/check-requirements	2023-05-16 09:51:25.000000000 -0500
@@ -59,7 +59,7 @@
         echo "pass (binary: $exe, version: $v, py2)"
         found_python="yes"
         break
-    elif echo "$v" | grep -q "^3.[2-8]"; then
+    elif echo "$v" | grep -q "^3.[1-9][0-9]*"; then
         echo "pass (binary: $exe, version: $v, py3)"
         found_python="yes"
         break
@@ -254,18 +254,21 @@
 done
 
 # check and warn if various firewall applications are installed
+echo "== System =="
+echo -n "Other firewall applications:"
 found=
 for exe in apf arno-iptables-firewall ferm firehol firewalld ipkungfu iptables-persistent netfilter-persistent pyroman uruk ; do
     if PATH=/sbin:/usr/sbin:/bin:/usr/bin which "$exe" >/dev/null 2>&1; then
         found="$found $exe"
     fi
 done
-if [ ! -z "$found" ]; then
-    echo "WARN: detected other firewall applications:"
-    echo "$found"
-    echo "(if enabled, these applications may interfere with ufw)"
-    echo ""
+if [ -z "$found" ]; then
+    echo " pass"
+else
+    echo -n "$found"
+    echo -n " (if enabled, may interfere with ufw)"
 fi
+echo ""
 
 if [ -n "$error" ] || [ -n "$error_runtime" ]; then
     if [ -n "$error" ]; then
diff -Nru ufw-0.36.1/tests/root/bugs/result ufw-0.36.2/tests/root/bugs/result
--- ufw-0.36.1/tests/root/bugs/result	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/tests/root/bugs/result	2023-05-18 08:06:28.000000000 -0500
@@ -67,14 +67,14 @@
 ip6tables -L -n:
 Chain INPUT (policy DROP)
 target     prot opt source               destination         
-ACCEPT     all      ::/0                 ::/0                
+ACCEPT     TST  --  ::/0                 ::/0                
 
 Chain FORWARD (policy DROP)
 target     prot opt source               destination         
 
 Chain OUTPUT (policy DROP)
 target     prot opt source               destination         
-ACCEPT     all      ::/0                 ::/0                
+ACCEPT     TST  --  ::/0                 ::/0                
 Bug #260881
 Setting IPV6 to no
 6: disable
@@ -94,7 +94,7 @@
 
 
 iptables -L -n:
-ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 /* 'dapp_Apache' */
+ACCEPT     TST    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 /* 'dapp_Apache' */
 
 10: delete allow Apache
 WARN: Checks disabled
diff -Nru ufw-0.36.1/tests/root/bugs/runtest.sh ufw-0.36.2/tests/root/bugs/runtest.sh
--- ufw-0.36.1/tests/root/bugs/runtest.sh	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/tests/root/bugs/runtest.sh	2023-05-18 08:06:28.000000000 -0500
@@ -38,7 +38,8 @@
 echo "/lib/ufw/ufw-init force-reload:" >> $TESTTMP/result
 $TESTSTATE/ufw-init force-reload 2>/dev/null >> $TESTTMP/result
 echo "ip6tables -L -n:" >> $TESTTMP/result
-ip6tables -L -n 2>/dev/null >> $TESTTMP/result
+# normalize 'ACCEPT {all,tcp}' and 'ACCEPT N' for old/new kernel/iptables
+ip6tables -L -n | sed 's/^ACCEPT \+[a-z0-9]\+ [ -]\+/ACCEPT     TST  --  /' 2>/dev/null >> $TESTTMP/result
 
 echo "Bug #260881" >> $TESTTMP/result
 echo "Setting IPV6 to no" >> $TESTTMP/result
@@ -48,7 +49,8 @@
 do_cmd "0"  allow Apache
 do_cmd "0"  delete deny Apache
 echo "iptables -L -n:" >> $TESTTMP/result
-iptables -L -n 2>/dev/null | grep -A1 "80" >> $TESTTMP/result
+# normalize 'ACCEPT {all,tcp}' and 'ACCEPT N' for old/new kernel/iptables
+iptables -L -n | sed 's/^ACCEPT \+[a-z0-9]\+ [ -]\+/ACCEPT     TST  --  /' 2>/dev/null | grep -A1 "80" >> $TESTTMP/result
 do_cmd "0"  delete allow Apache
 echo "iptables -L -n:" >> $TESTTMP/result
 iptables -L -n 2>/dev/null | grep -A1 "80" >> $TESTTMP/result
diff -Nru ufw-0.36.1/tests/root/live/result ufw-0.36.2/tests/root/live/result
--- ufw-0.36.1/tests/root/live/result	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/tests/root/live/result	2023-05-18 08:06:28.000000000 -0500
@@ -634,7 +634,7 @@
 86: enable
 
 
-ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            /* ufw_test_builtins */
+ACCEPT     TST  --  0.0.0.0/0            0.0.0.0/0            /* ufw_test_builtins */
 Testing status numbered
 Setting IPV6 to yes
 87: disable
diff -Nru ufw-0.36.1/tests/root/live/runtest.sh ufw-0.36.2/tests/root/live/runtest.sh
--- ufw-0.36.1/tests/root/live/runtest.sh	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/tests/root/live/runtest.sh	2023-05-18 08:06:28.000000000 -0500
@@ -110,7 +110,8 @@
         echo iptables -I INPUT -j ACCEPT -m comment --comment $str >> $TESTTMP/result
         iptables -I INPUT -j ACCEPT -m comment --comment $str >> $TESTTMP/result
         do_cmd "0" nostats enable
-        iptables -n -L INPUT 2>/dev/null | grep "$str" >> $TESTTMP/result
+        # normalize 'ACCEPT {all,tcp}' and 'ACCEPT N' for old/new kernel/iptables
+        iptables -n -L INPUT | sed 's/^ACCEPT \+[a-z0-9]\+ [ -]\+/ACCEPT     TST  --  /' 2>/dev/null | grep "$str" >> $TESTTMP/result
         iptables -D INPUT -j ACCEPT -m comment --comment $str 2>/dev/null
 done
 
diff -Nru ufw-0.36.1/tests/root/live_route/result ufw-0.36.2/tests/root/live_route/result
--- ufw-0.36.1/tests/root/live_route/result	2018-12-14 12:25:55.000000000 -0600
+++ ufw-0.36.2/tests/root/live_route/result	2023-05-18 08:06:28.000000000 -0500
@@ -572,7 +572,7 @@
 79: enable
 
 
-ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            /* ufw_test_builtins */
+ACCEPT     TST  --  0.0.0.0/0            0.0.0.0/0            /* ufw_test_builtins */
 Testing status numbered
 Setting IPV6 to yes
 80: disable
diff -Nru ufw-0.36.1/tests/root/live_route/runtest.sh ufw-0.36.2/tests/root/live_route/runtest.sh
--- ufw-0.36.1/tests/root/live_route/runtest.sh	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/tests/root/live_route/runtest.sh	2023-05-18 08:06:28.000000000 -0500
@@ -99,7 +99,8 @@
         echo iptables -I FORWARD -j ACCEPT -m comment --comment $str >> $TESTTMP/result
         iptables -I FORWARD -j ACCEPT -m comment --comment $str >> $TESTTMP/result
         do_cmd "0" nostats enable
-        iptables -n -L FORWARD 2>/dev/null | grep "$str" >> $TESTTMP/result
+        # normalize 'ACCEPT {all,tcp}' and 'ACCEPT N' for old/new kernel/iptables
+        iptables -n -L FORWARD | sed 's/^ACCEPT \+[a-z0-9]\+ [ -]\+/ACCEPT     TST  --  /' 2>/dev/null | grep "$str" >> $TESTTMP/result
         iptables -D FORWARD -j ACCEPT -m comment --comment $str 2>/dev/null
 done
 
diff -Nru ufw-0.36.1/tests/unit/test_applications.py ufw-0.36.2/tests/unit/test_applications.py
--- ufw-0.36.1/tests/unit/test_applications.py	2018-12-14 12:25:55.000000000 -0600
+++ ufw-0.36.2/tests/unit/test_applications.py	2023-05-18 08:07:39.000000000 -0500
@@ -117,6 +117,9 @@
                     {'title': 'bad protocol - ipv6',
                      'description': 'desc',
                      'ports': '80/ipv6'},
+                    {'title': 'bad protocol - vrrp',
+                     'description': 'desc',
+                     'ports': '80/vrrp'},
                     ]
         for p in profiles:
             print(" %s" % p)
diff -Nru ufw-0.36.1/tests/unit/test_common.py ufw-0.36.2/tests/unit/test_common.py
--- ufw-0.36.1/tests/unit/test_common.py	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/tests/unit/test_common.py	2023-05-18 08:07:39.000000000 -0500
@@ -261,7 +261,7 @@
     def test_set_protocol(self):
         '''Test set_protocol()'''
         r = self.rules["any"]
-        for proto in ['any', 'tcp', 'udp', 'ipv6', 'esp', 'ah']:
+        for proto in ['any', 'tcp', 'udp', 'ipv6', 'esp', 'ah', 'vrrp']:
             r.set_protocol(proto)
             self.assertEquals(proto, r.protocol, "%s != %s" %
                               (proto, r.protocol))
diff -Nru ufw-0.36.1/tests/unit/test_parser.py ufw-0.36.2/tests/unit/test_parser.py
--- ufw-0.36.1/tests/unit/test_parser.py	2021-09-18 19:50:19.000000000 -0500
+++ ufw-0.36.2/tests/unit/test_parser.py	2023-05-18 08:07:39.000000000 -0500
@@ -428,6 +428,7 @@
                 ['deny', 'to', 'any', 'proto', 'ipv6'],
                 ['allow', 'to', 'any', 'proto', 'igmp'],
                 ['reject', 'to', 'any', 'proto', 'esp'],
+                ['allow', 'to', 'any', 'proto', 'vrrp'],
                 ['deny', 'to', '224.0.0.1', 'proto', 'igmp'],
                 ['deny', 'in', 'on', 'eth0', 'to', '224.0.0.1', 'proto', \
                  'igmp'],
@@ -435,6 +436,8 @@
                  'gre'],
                 ['deny', 'to', 'any', 'proto', 'ah'],
                 ['allow', 'out', 'on', 'br_lan'],
+                ['allow', 'in', 'on', 'eth0', 'to', '192.168.0.1', 'from', \
+                 '224.0.0.0/24', 'proto', 'vrrp'],
                ]
         count = 0
         for rtype in ['route', 'rule']:
@@ -524,6 +527,8 @@
                  ufw.common.UFWError),
                 (['rule', 'deny', 'to', 'any', 'port', '22', 'proto', 'gre'],
                  ufw.common.UFWError),
+                (['rule', 'deny', 'to', 'any', 'port', '22', 'proto', 'vrrp'],
+                 ufw.common.UFWError),
                 (['rule', 'allow', 'to', '192.168.0.0/16', 'app', 'Samba',
                   'from', '192.168.0.0/16', 'port', 'tcpmux'],
                   ufw.common.UFWError),
diff -Nru ufw-0.36.1/tests/unit/test_util.py ufw-0.36.2/tests/unit/test_util.py
--- ufw-0.36.1/tests/unit/test_util.py	2018-12-14 12:25:55.000000000 -0600
+++ ufw-0.36.2/tests/unit/test_util.py	2023-05-18 08:07:39.000000000 -0500
@@ -741,6 +741,42 @@
         tests.unit.support.check_for_exception(self, IOError, \
                                                ufw.util.get_ppid, 0)
 
+    def test_get_ppid_no_space(self):
+        """Test get_ppid() no space"""
+        if sys.version_info[0] < 3:
+            return tests.unit.support.skipped(self, "skipping with python2")
+        import unittest.mock
+
+        m = unittest.mock.mock_open(read_data="9983 (cmd) S 923 9983 ...\n")
+        with unittest.mock.patch("builtins.open", m):
+            with unittest.mock.patch("os.path.isfile", return_value=True):
+                ppid = ufw.util.get_ppid(9983)
+                self.assertEquals(ppid, 923, "%d' != '923'" % ppid)
+
+    def test_get_ppid_with_space(self):
+        """Test get_ppid() with space"""
+        if sys.version_info[0] < 3:
+            return tests.unit.support.skipped(self, "skipping with python2")
+        import unittest.mock
+
+        m = unittest.mock.mock_open(read_data="9983 (cmd with space) S 923 9983 ...\n")
+        with unittest.mock.patch("builtins.open", m):
+            with unittest.mock.patch("os.path.isfile", return_value=True):
+                ppid = ufw.util.get_ppid(9983)
+                self.assertEquals(ppid, 923, "%d' != '923'" % ppid)
+
+    def test_get_ppid_with_parens(self):
+        """Test get_ppid() with parens"""
+        if sys.version_info[0] < 3:
+            return tests.unit.support.skipped(self, "skipping with python2")
+        import unittest.mock
+
+        m = unittest.mock.mock_open(read_data="9983 (cmd(paren)) S 923 9983 ...\n")
+        with unittest.mock.patch("builtins.open", m):
+            with unittest.mock.patch("os.path.isfile", return_value=True):
+                ppid = ufw.util.get_ppid(9983)
+                self.assertEquals(ppid, 923, "%d' != '923'" % ppid)
+
     def test_under_ssh(self):
         '''Test under_ssh()'''
         # this test could be running under ssh, so can't do anything more
@@ -1025,6 +1061,25 @@
         result = ufw.util.hex_decode(s)
         self.assertEquals(expected, result)
 
+        # test odd length string mitigation by truncating one hex-digit. This
+        # should result in the last (odd) hex digit being dropped and a decoded
+        # string of one less character
+        expected = "foo👍bar字ba"
+        if sys.version_info[0] < 3:
+            expected = u"foo👍bar字ba"
+        result = ufw.util.hex_decode(s[:-1])
+        self.assertEquals(expected, result)
+
+        # test odd length string mitigation by removing first hex-digit. This
+        # should result in the last (odd) hex digit being dropped, but since
+        # the first hex digit was removed, the byte sequence is shifted by one
+        # which causes the whole string to be 'backslashreplace'd.
+        expected = "f\\xf6\\xff\t\\xf9\x18\\xd6&\x17.Z\\xd9v&\x17"
+        if sys.version_info[0] < 3:
+            expected = u"f\\xf6\\xff\t\\xf9\x18\\xd6&\x17.Z\\xd9v&\x17"
+        result = ufw.util.hex_decode(s[1:])
+        self.assertEquals(expected, result)
+
     def test_create_lock(self):
         '''Test create_lock()'''
         lock = ufw.util.create_lock(dryrun=True)

--- End Message ---
--- Begin Message ---
Hi

On 24-05-2023 03:18, Jamie Strandboge wrote:
Hopefully this answers your questions. Thanks for your consideration!

Please don't repeat a similar situation in trixie, but unblocked now.

Paul

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


--- End Message ---

Reply to: