diff --git a/CHANGELOG b/CHANGELOG index c44e004b..ba82e320 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ jc changelog - Fix `acpi` command parser for "Not charging" battery status lines - Fix `iwconfig` command parser for SSIDs with dashes in the name - Fix `crontab` command parsers for incorrect variable parsing in some cases +- Fix `ufw-appinfo` command parser for parsing errors on multiline description fields - Fix pytest warnings 20230323 v1.23.1 diff --git a/docs/parsers/ufw_appinfo.md b/docs/parsers/ufw_appinfo.md index 24c3848d..f66e56eb 100644 --- a/docs/parsers/ufw_appinfo.md +++ b/docs/parsers/ufw_appinfo.md @@ -161,4 +161,4 @@ Returns: ### Parser Information Compatibility: linux -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index f893181e..be6410c9 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -138,7 +138,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`ufw app info [application]` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -289,6 +289,7 @@ def parse(data, raw=False, quiet=False): if line.startswith('--'): if item_obj: raw_output.append(item_obj) + ports = False item_obj = {} continue diff --git a/man/jc.1 b/man/jc.1 index 80533232..eef2cb0e 100644 --- a/man/jc.1 +++ b/man/jc.1 @@ -1,4 +1,4 @@ -.TH jc 1 2023-04-17 1.23.2 "JSON Convert" +.TH jc 1 2023-04-18 1.23.2 "JSON Convert" .SH NAME \fBjc\fP \- JSON Convert JSONifies the output of many CLI tools, file-types, and strings diff --git a/tests/fixtures/generic/ufw-appinfo-multiline-description.json b/tests/fixtures/generic/ufw-appinfo-multiline-description.json new file mode 100644 index 00000000..a1873e23 --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-multiline-description.json @@ -0,0 +1 @@ +[{"profile":"AIM","title":"AIM Talk","description":"AIM talk protocol","tcp_list":[5190],"normalized_tcp_list":[5190]},{"profile":"Bonjour","title":"Bonjour","description":"Bonjour protocol","udp_list":[5353,5298],"tcp_list":[5298],"normalized_tcp_list":[5298],"normalized_udp_list":[5298,5353]},{"profile":"CIFS","title":"SMB/CIFS server","description":"SMB/CIFS server","udp_list":[137,138],"tcp_list":[139,445],"normalized_tcp_list":[139,445],"normalized_udp_list":[137,138]},{"profile":"DNS","title":"Internet Domain Name Server","description":"Internet Domain Name Server","tcp_list":[53],"udp_list":[53],"normalized_tcp_list":[53],"normalized_udp_list":[53]},{"profile":"Deluge","title":"Deluge","description":"Deluge BitTorrent client","tcp_ranges":[{"start":6881,"end":6891}],"normalized_tcp_ranges":[{"start":6881,"end":6891}]},{"profile":"IMAP","title":"Mail server (IMAP)","description":"Mail server (IMAP)","tcp_list":[143],"normalized_tcp_list":[143]},{"profile":"IMAPS","title":"Secure mail server (IMAPS)","description":"Secure mail server (IMAPS)","tcp_list":[993],"normalized_tcp_list":[993]},{"profile":"IPP","title":"Cups server (IPP)","description":"Cups server (IPP)","tcp_list":[631],"udp_list":[631],"normalized_tcp_list":[631],"normalized_udp_list":[631]},{"profile":"Icinga","title":"Icinga","description":"Icinga monitoring","tcp_list":[5665],"normalized_tcp_list":[5665]},{"profile":"KTorrent","title":"KTorrent","description":"KTorrent BitTorrent client","tcp_list":[6881],"udp_list":[4444],"normalized_tcp_list":[6881],"normalized_udp_list":[4444]},{"profile":"Kerberos Admin","title":"Kerberos v5 admin","description":"Kerberos v5 server","tcp_list":[749],"normalized_tcp_list":[749]},{"profile":"Kerberos Full","title":"Kerberos v5 server","description":"Kerberos v5 server","tcp_list":[88,749],"udp_list":[464],"normalized_tcp_list":[88,749],"normalized_udp_list":[464]},{"profile":"Kerberos KDC","title":"Kerberos v5 KDC server","description":"Kerberos v5 KDC server","tcp_list":[88],"udp_list":[88],"normalized_tcp_list":[88],"normalized_udp_list":[88]},{"profile":"Kerberos Password","title":"Kerberos v5 password","description":"Kerberos v5 password","udp_list":[464],"normalized_udp_list":[464]},{"profile":"LDAP","title":"LDAP server","description":"LDAP server","tcp_list":[389],"normalized_tcp_list":[389]},{"profile":"LDAPS","title":"LDAP server (LDAPS)","description":"LDAP server (LDAPS)","tcp_list":[636],"normalized_tcp_list":[636]},{"profile":"LPD","title":"LPD server","description":"LPD server","tcp_list":[515],"normalized_tcp_list":[515]},{"profile":"MSN","title":"MSN Chat","description":"MSN chat protocol (with file transfer and voice)","tcp_list":[1863,6901],"udp_list":[1863,6901],"tcp_ranges":[{"start":6891,"end":6900}],"normalized_tcp_list":[1863,6901],"normalized_tcp_ranges":[{"start":6891,"end":6900}],"normalized_udp_list":[1863,6901]},{"profile":"MSN SSL","title":"MSN Chat (SSL)","description":"MSN chat protocol (SSL)","tcp_list":[443],"normalized_tcp_list":[443]},{"profile":"Mail submission","title":"Mail server (Submission)","description":"Mail server (Submission)","tcp_list":[587],"normalized_tcp_list":[587]},{"profile":"Munin","title":"Munin","description":"Munin monitoring","tcp_list":[4949],"normalized_tcp_list":[4949]},{"profile":"NFS","title":"NFS server","description":"NFS and portmap server. Will also need access to mountd, statd","tcp_list":[2049,111],"udp_list":[2049,111],"normalized_tcp_list":[111,2049],"normalized_udp_list":[111,2049]},{"profile":"Nginx Full","title":"Web Server (Nginx, HTTP + HTTPS)","description":"Small, but very powerful and efficient web server","tcp_list":[80,443],"normalized_tcp_list":[80,443]},{"profile":"Nginx HTTP","title":"Web Server (Nginx, HTTP)","description":"Small, but very powerful and efficient web server","tcp_list":[80],"normalized_tcp_list":[80]},{"profile":"Nginx HTTPS","title":"Web Server (Nginx, HTTPS)","description":"Small, but very powerful and efficient web server","tcp_list":[443],"normalized_tcp_list":[443]},{"profile":"OpenSSH","title":"Secure shell server, an rshd replacement","description":"OpenSSH is a free implementation of the Secure Shell protocol.","tcp_list":[22],"normalized_tcp_list":[22]},{"profile":"POP3","title":"Mail server (POP3)","description":"Mail server (POP3)","tcp_list":[110],"normalized_tcp_list":[110]},{"profile":"POP3S","title":"Secure mail server (POP3S)","description":"Secure mail server (POP3S)","tcp_list":[995],"normalized_tcp_list":[995]},{"profile":"PeopleNearby","title":"People Nearby","description":"People Nearby (Bonjour/Salut) functionality in Empathy","udp_list":[5353,5298],"tcp_list":[5298],"normalized_tcp_list":[5298],"normalized_udp_list":[5298,5353]},{"profile":"RabbitMQ","title":"RabbitMQ","description":"RabbitMQ is the most widely deployed open source message","tcp_list":[25672],"tcp_ranges":[{"start":35672,"end":35682}],"normalized_tcp_list":[25672],"normalized_tcp_ranges":[{"start":35672,"end":35682}]},{"profile":"SMTP","title":"Mail server (SMTP)","description":"Mail server (SMTP)","tcp_list":[25],"normalized_tcp_list":[25]},{"profile":"SSH","title":"SSH server","description":"SSH server","tcp_list":[22],"normalized_tcp_list":[22]},{"profile":"Socks","title":"Socks proxy","description":"Socks proxy","tcp_list":[1080],"normalized_tcp_list":[1080]},{"profile":"Telnet","title":"Telnet server (insecure)","description":"Telnet server (insecure)","tcp_list":[23],"normalized_tcp_list":[23]},{"profile":"Transmission","title":"Transmission","description":"Transmission BitTorrent client","tcp_list":[51413],"udp_list":[51413],"normalized_tcp_list":[51413],"normalized_udp_list":[51413]},{"profile":"Transparent Proxy","title":"Transparent proxy","description":"Transparent proxy","tcp_list":[8081],"normalized_tcp_list":[8081]},{"profile":"Turnserver","title":"Coturn Turnserver","description":"Free open source implementation of TURN and STUN Server","tcp_list":[3478,3479,5349,5350],"tcp_ranges":[{"start":49152,"end":65535}],"udp_list":[3478,3479,5349,5350],"udp_ranges":[{"start":49152,"end":65535}],"normalized_tcp_list":[3478,3479,5349,5350],"normalized_tcp_ranges":[{"start":49152,"end":65535}],"normalized_udp_list":[3478,3479,5349,5350],"normalized_udp_ranges":[{"start":49152,"end":65535}]},{"profile":"VNC","title":"VNC server","description":"VNC server","tcp_list":[5900],"normalized_tcp_list":[5900]},{"profile":"WWW","title":"Web Server","description":"Web server","tcp_list":[80],"normalized_tcp_list":[80]},{"profile":"WWW Cache","title":"Web Server (8080)","description":"Web Server (8080)","tcp_list":[8080],"normalized_tcp_list":[8080]},{"profile":"WWW Full","title":"Web Server (HTTP,HTTPS)","description":"Web Server (HTTP,HTTPS)","tcp_list":[80,443],"normalized_tcp_list":[80,443]},{"profile":"WWW Secure","title":"Web Server (HTTPS)","description":"Web Server (HTTPS)","tcp_list":[443],"normalized_tcp_list":[443]},{"profile":"XMPP","title":"XMPP Chat","description":"XMPP protocol (Jabber and Google Talk)","tcp_list":[5269],"normalized_tcp_list":[5269]},{"profile":"Yahoo","title":"Yahoo Chat","description":"Yahoo chat protocol","tcp_list":[5050],"udp_list":[5050],"normalized_tcp_list":[5050],"normalized_udp_list":[5050]},{"profile":"qBittorrent","title":"qBittorrent","description":"qBittorrent BitTorrent client","tcp_list":[6881],"normalized_tcp_list":[6881]},{"profile":"svnserve","title":"Subversion server","description":"Subversion server for access to Subversion repositories.","tcp_list":[3690],"normalized_tcp_list":[3690]}] diff --git a/tests/fixtures/generic/ufw-appinfo-multiline-description.out b/tests/fixtures/generic/ufw-appinfo-multiline-description.out new file mode 100644 index 00000000..be889fe9 --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-multiline-description.out @@ -0,0 +1,428 @@ +Profile: AIM +Title: AIM Talk +Description: AIM talk protocol + +Port: + 5190/tcp + +-- + +Profile: Bonjour +Title: Bonjour +Description: Bonjour protocol + +Ports: + 5353/udp + 5298 + +-- + +Profile: CIFS +Title: SMB/CIFS server +Description: SMB/CIFS server + +Ports: + 137,138/udp + 139,445/tcp + +-- + +Profile: DNS +Title: Internet Domain Name Server +Description: Internet Domain Name Server + +Port: + 53 + +-- + +Profile: Deluge +Title: Deluge +Description: Deluge BitTorrent client + +Port: + 6881:6891/tcp + +-- + +Profile: IMAP +Title: Mail server (IMAP) +Description: Mail server (IMAP) + +Port: + 143/tcp + +-- + +Profile: IMAPS +Title: Secure mail server (IMAPS) +Description: Secure mail server (IMAPS) + +Port: + 993/tcp + +-- + +Profile: IPP +Title: Cups server (IPP) +Description: Cups server (IPP) + +Port: + 631 + +-- + +Profile: Icinga +Title: Icinga +Description: Icinga monitoring + +Port: + 5665/tcp + +-- + +Profile: KTorrent +Title: KTorrent +Description: KTorrent BitTorrent client + +Ports: + 6881/tcp + 4444/udp + +-- + +Profile: Kerberos Admin +Title: Kerberos v5 admin +Description: Kerberos v5 server + +Port: + 749/tcp + +-- + +Profile: Kerberos Full +Title: Kerberos v5 server +Description: Kerberos v5 server + +Ports: + 88,749/tcp + 464/udp + +-- + +Profile: Kerberos KDC +Title: Kerberos v5 KDC server +Description: Kerberos v5 KDC server + +Port: + 88 + +-- + +Profile: Kerberos Password +Title: Kerberos v5 password +Description: Kerberos v5 password + +Port: + 464/udp + +-- + +Profile: LDAP +Title: LDAP server +Description: LDAP server + +Port: + 389/tcp + +-- + +Profile: LDAPS +Title: LDAP server (LDAPS) +Description: LDAP server (LDAPS) + +Port: + 636/tcp + +-- + +Profile: LPD +Title: LPD server +Description: LPD server + +Port: + 515/tcp + +-- + +Profile: MSN +Title: MSN Chat +Description: MSN chat protocol (with file transfer and voice) + +Ports: + 1863 + 6891:6900/tcp + 6901 + +-- + +Profile: MSN SSL +Title: MSN Chat (SSL) +Description: MSN chat protocol (SSL) + +Port: + 443/tcp + +-- + +Profile: Mail submission +Title: Mail server (Submission) +Description: Mail server (Submission) + +Port: + 587/tcp + +-- + +Profile: Munin +Title: Munin +Description: Munin monitoring + +Port: + 4949/tcp + +-- + +Profile: NFS +Title: NFS server +Description: NFS and portmap server. Will also need access to mountd, statd +and possibly others + +Ports: + 2049,111/tcp + 2049,111/udp + +-- + +Profile: Nginx Full +Title: Web Server (Nginx, HTTP + HTTPS) +Description: Small, but very powerful and efficient web server + +Ports: + 80,443/tcp + +-- + +Profile: Nginx HTTP +Title: Web Server (Nginx, HTTP) +Description: Small, but very powerful and efficient web server + +Port: + 80/tcp + +-- + +Profile: Nginx HTTPS +Title: Web Server (Nginx, HTTPS) +Description: Small, but very powerful and efficient web server + +Port: + 443/tcp + +-- + +Profile: OpenSSH +Title: Secure shell server, an rshd replacement +Description: OpenSSH is a free implementation of the Secure Shell protocol. + +Port: + 22/tcp + +-- + +Profile: POP3 +Title: Mail server (POP3) +Description: Mail server (POP3) + +Port: + 110/tcp + +-- + +Profile: POP3S +Title: Secure mail server (POP3S) +Description: Secure mail server (POP3S) + +Port: + 995/tcp + +-- + +Profile: PeopleNearby +Title: People Nearby +Description: People Nearby (Bonjour/Salut) functionality in Empathy + +Ports: + 5353/udp + 5298 + +-- + +Profile: RabbitMQ +Title: RabbitMQ +Description: RabbitMQ is the most widely deployed open source message +broker. + +Ports: + 4369/tcp + 5671:5672/tcp + 5551:5552/tcp + 6000:6500/tcp + 25672/tcp + 35672:35682/tcp + +-- + +Profile: SMTP +Title: Mail server (SMTP) +Description: Mail server (SMTP) + +Port: + 25/tcp + +-- + +Profile: SSH +Title: SSH server +Description: SSH server + +Port: + 22/tcp + +-- + +Profile: Socks +Title: Socks proxy +Description: Socks proxy + +Port: + 1080/tcp + +-- + +Profile: Telnet +Title: Telnet server (insecure) +Description: Telnet server (insecure) + +Port: + 23/tcp + +-- + +Profile: Transmission +Title: Transmission +Description: Transmission BitTorrent client + +Port: + 51413 + +-- + +Profile: Transparent Proxy +Title: Transparent proxy +Description: Transparent proxy + +Port: + 8081/tcp + +-- + +Profile: Turnserver +Title: Coturn Turnserver +Description: Free open source implementation of TURN and STUN Server + +Ports: + 3478,3479,5349,5350,49152:65535/tcp + 3478,3479,5349,5350,49152:65535/udp + +-- + +Profile: VNC +Title: VNC server +Description: VNC server + +Port: + 5900/tcp + +-- + +Profile: WWW +Title: Web Server +Description: Web server + +Port: + 80/tcp + +-- + +Profile: WWW Cache +Title: Web Server (8080) +Description: Web Server (8080) + +Port: + 8080/tcp + +-- + +Profile: WWW Full +Title: Web Server (HTTP,HTTPS) +Description: Web Server (HTTP,HTTPS) + +Ports: + 80,443/tcp + +-- + +Profile: WWW Secure +Title: Web Server (HTTPS) +Description: Web Server (HTTPS) + +Port: + 443/tcp + +-- + +Profile: XMPP +Title: XMPP Chat +Description: XMPP protocol (Jabber and Google Talk) + +Ports: + 5222/tcp + 5269/tcp + +-- + +Profile: Yahoo +Title: Yahoo Chat +Description: Yahoo chat protocol + +Port: + 5050 + +-- + +Profile: qBittorrent +Title: qBittorrent +Description: qBittorrent BitTorrent client + +Port: + 6881/tcp + +-- + +Profile: svnserve +Title: Subversion server +Description: Subversion server for access to Subversion repositories. + +Port: + 3690/tcp diff --git a/tests/test_ufw_appinfo.py b/tests/test_ufw_appinfo.py index caf6eea3..e13ddb7c 100644 --- a/tests/test_ufw_appinfo.py +++ b/tests/test_ufw_appinfo.py @@ -24,6 +24,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-msn.out'), 'r', encoding='utf-8') as f: generic_ufw_appinfo_msn = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-multiline-description.out'), 'r', encoding='utf-8') as f: + generic_ufw_appinfo_multiline_description = f.read() + # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ufw-appinfo-all.json'), 'r', encoding='utf-8') as f: ubuntu_18_04_ufw_appinfo_all_json = json.loads(f.read()) @@ -40,6 +43,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-msn.json'), 'r', encoding='utf-8') as f: generic_ufw_appinfo_msn_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-multiline-description.json'), 'r', encoding='utf-8') as f: + generic_ufw_appinfo_multiline_description_json = json.loads(f.read()) + def test_ufw_appinfo_nodata(self): """ @@ -77,6 +83,12 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.ufw_appinfo.parse(self.generic_ufw_appinfo_msn, quiet=True), self.generic_ufw_appinfo_msn_json) + def test_ufw_appinfo_generic_multiline_description(self): + """ + Test 'ufw app info all' with mult-line description field + """ + self.assertEqual(jc.parsers.ufw_appinfo.parse(self.generic_ufw_appinfo_multiline_description, quiet=True), self.generic_ufw_appinfo_multiline_description_json) + if __name__ == '__main__': unittest.main()