1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-06-23 00:29:59 +02:00

add sshd_conf parser

This commit is contained in:
Kelly Brazil
2022-10-28 15:15:02 -07:00
parent c405309742
commit f5988527fb
6 changed files with 528 additions and 0 deletions

View File

@ -1,8 +1,11 @@
jc changelog jc changelog
20221025 v1.22.2 20221025 v1.22.2
- add `sshd_conf` parser
- fix `csv` and `csv-s` parsers for UTF-8 encoded CSV files with leading BOM bytes - fix `csv` and `csv-s` parsers for UTF-8 encoded CSV files with leading BOM bytes
- fix exit code to be non-zero on interrupt - fix exit code to be non-zero on interrupt
- allow parser module objects to be used as arguments to `jc.get_help()` and `jc.parser_info()`
- catch unexpected exceptions in the CLI
- add error message on interrupt to STDERR - add error message on interrupt to STDERR
- add python 3.11 tests to github actions - add python 3.11 tests to github actions

View File

@ -148,6 +148,7 @@ parsers: List[str] = [
'sfdisk', 'sfdisk',
'shadow', 'shadow',
'ss', 'ss',
'sshd-conf',
'stat', 'stat',
'stat-s', 'stat-s',
'sysctl', 'sysctl',

189
jc/parsers/sshd_conf.py Normal file
View File

@ -0,0 +1,189 @@
"""jc - JSON Convert `sshd -T` command output parser
<<Short sshd_conf description and caveats>>
Usage (cli):
$ sshd -T | jc --sshd-conf
or
$ jc sshd -T
Usage (module):
import jc
result = jc.parse('sshd_conf', sshd_command_output)
Schema:
[
{
"sshd_conf": string,
"bar": boolean,
"baz": integer
}
]
Examples:
$ sshd_conf | jc --sshd_conf -p
[]
$ sshd_conf | jc --sshd_conf -p -r
[]
"""
from typing import Set, List, Dict
from jc.jc_types import JSONDictType
import jc.utils
class info():
"""Provides parser metadata (version, author, etc.)"""
version = '1.0'
description = '`sshd -T` command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
compatible = ['linux', 'darwin', 'freebsd']
magic_commands = ['sshd -T']
__version__ = info.version
def _process(proc_data: JSONDictType) -> JSONDictType:
"""
Final processing to conform to the schema.
Parameters:
proc_data: (List of Dictionaries) raw structured data to process
Returns:
List of Dictionaries. Structured to conform to the schema.
"""
split_fields_space: Set[str] = {
'authorizedkeysfile', 'include', 'ipqos', 'permitlisten', 'permitopen'
}
split_fields_comma: Set[str] = {
'casignaturealgorithms', 'ciphers', 'gssapikexalgorithms', 'hostbasedacceptedalgorithms',
'hostbasedacceptedkeytypes', 'hostkeyalgorithms', 'kexalgorithms', 'macs',
'pubkeyacceptedalgorithms', 'pubkeyacceptedkeytypes'
}
int_list: Set[str] = {'clientalivecountmax', 'clientaliveinterval', 'logingracetime',
'maxauthtries', 'maxsessions', 'maxstartups', 'maxstartups_rate', 'maxstartups_full',
'rekeylimit', 'rekeylimit_time', 'x11displayoffset', 'x11maxdisplays'
}
dict_copy = proc_data.copy()
for key, val in dict_copy.items():
# this is a list value
if key == 'acceptenv':
new_list: List[str] = []
for item in val: # type: ignore
new_list.extend(item.split())
proc_data[key] = new_list
continue
if key == 'maxstartups':
maxstart_split = val.split(':', maxsplit=2) # type: ignore
proc_data[key] = maxstart_split[0]
if len(maxstart_split) > 1:
proc_data[key + '_rate'] = maxstart_split[1]
if len(maxstart_split) > 2:
proc_data[key + '_full'] = maxstart_split[2]
continue
if key == 'port':
port_list: List[int] = []
for item in val: # type: ignore
port_list.append(int(item))
proc_data[key] = port_list
continue
if key == 'rekeylimit':
rekey_split = val.split(maxsplit=1) # type: ignore
proc_data[key] = rekey_split[0]
if len(rekey_split) > 1:
proc_data[key + '_time'] = rekey_split[1]
continue
if key == 'subsystem':
rekey_split = val.split(maxsplit=1) # type: ignore
proc_data[key] = rekey_split[0]
if len(rekey_split) > 1:
proc_data[key + '_command'] = rekey_split[1]
continue
if key in split_fields_space:
proc_data[key] = val.split() # type: ignore
continue
if key in split_fields_comma:
proc_data[key] = val.split(',') # type: ignore
continue
for key, val in proc_data.items():
if key in int_list:
proc_data[key] = jc.utils.convert_to_int(val)
return proc_data
def parse(
data: str,
raw: bool = False,
quiet: bool = False
) -> JSONDictType:
"""
Main text parsing function
Parameters:
data: (string) text data to parse
raw: (boolean) unprocessed output if True
quiet: (boolean) suppress warning messages if True
Returns:
List of Dictionaries. Raw or processed structured data.
"""
jc.utils.compatibility(__name__, info.compatible, quiet)
jc.utils.input_type_check(data)
raw_output: Dict = {}
multi_fields: Set[str] = {'acceptenv', 'hostkey', 'listenaddress', 'port'}
modified_fields: Set[str] = {'casignaturealgorithms', 'ciphers', 'hostbasedacceptedalgorithms',
'kexalgorithms', 'macs', 'pubkeyacceptedalgorithms'
}
modifiers: Set[str] = {'+', '-', '^'}
if jc.utils.has_data(data):
for line in filter(None, data.splitlines()):
# support configuration file by skipping commented lines
if line.strip().startswith('#'):
continue
key, val = line.split(maxsplit=1)
# support configuration file by converting to lower case
key = key.lower()
if key in multi_fields:
if key not in raw_output:
raw_output[key] = []
raw_output[key].append(val)
continue
if key in modified_fields and val[0] in modifiers:
raw_output[key] = val[1:]
raw_output[key + '_strategy'] = val[0]
continue
raw_output[key] = val
continue
return raw_output if raw else _process(raw_output)

View File

@ -0,0 +1,104 @@
port 22
addressfamily any
listenaddress [::]:22
listenaddress 0.0.0.0:22
usepam yes
logingracetime 120
x11displayoffset 10
x11maxdisplays 1000
maxauthtries 6
maxsessions 10
clientaliveinterval 0
clientalivecountmax 3
streamlocalbindmask 0177
permitrootlogin yes
ignorerhosts yes
ignoreuserknownhosts no
hostbasedauthentication no
hostbasedusesnamefrompacketonly no
pubkeyauthentication yes
kerberosauthentication no
kerberosorlocalpasswd yes
kerberosticketcleanup yes
gssapiauthentication yes
gssapicleanupcredentials no
gssapikeyexchange no
gssapistrictacceptorcheck yes
gssapistorecredentialsonrekey no
gssapikexalgorithms gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1-
passwordauthentication yes
kbdinteractiveauthentication no
challengeresponseauthentication no
printmotd yes
printlastlog yes
x11forwarding yes
x11uselocalhost yes
permittty yes
permituserrc yes
strictmodes yes
tcpkeepalive yes
permitemptypasswords no
permituserenvironment no
compression yes
gatewayports no
showpatchlevel no
usedns yes
allowtcpforwarding yes
allowagentforwarding yes
disableforwarding no
allowstreamlocalforwarding yes
streamlocalbindunlink no
useprivilegeseparation sandbox
kerberosusekuserok yes
gssapienablek5users no
exposeauthenticationmethods never
fingerprinthash SHA256
pidfile /var/run/sshd.pid
xauthlocation /usr/bin/xauth
ciphers chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc,blowfish-cbc,cast128-cbc,3des-cbc
macs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
banner none
forcecommand none
chrootdirectory none
trustedusercakeys none
revokedkeys none
authorizedprincipalsfile none
versionaddendum none
authorizedkeyscommand none
authorizedkeyscommanduser none
authorizedprincipalscommand none
authorizedprincipalscommanduser none
hostkeyagent none
kexalgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
hostbasedacceptedkeytypes ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss
hostkeyalgorithms ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss
pubkeyacceptedkeytypes ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss
loglevel INFO
syslogfacility AUTHPRIV
authorizedkeysfile .ssh/authorized_keys
hostkey /etc/ssh/ssh_host_rsa_key
hostkey /etc/ssh/ssh_host_ecdsa_key
hostkey /etc/ssh/ssh_host_ed25519_key
acceptenv LANG
acceptenv LC_CTYPE
acceptenv LC_NUMERIC
acceptenv LC_TIME
acceptenv LC_COLLATE
acceptenv LC_MONETARY
acceptenv LC_MESSAGES
acceptenv LC_PAPER
acceptenv LC_NAME
acceptenv LC_ADDRESS
acceptenv LC_TELEPHONE
acceptenv LC_MEASUREMENT
acceptenv LC_IDENTIFICATION
acceptenv LC_ALL
acceptenv LANGUAGE
acceptenv XMODIFIERS
authenticationmethods any
subsystem sftp /usr/libexec/openssh/sftp-server
maxstartups 10:30:100
permittunnel no
ipqos lowdelay throughput
rekeylimit 0 0
permitopen any

92
tests/fixtures/generic/sshd-T.out vendored Normal file
View File

@ -0,0 +1,92 @@
acceptenv LANG
acceptenv LC_*
acceptenv test1 test2
addressfamily any
allowagentforwarding yes
allowstreamlocalforwarding yes
allowtcpforwarding yes
authenticationmethods any
authorizedkeyscommand none
authorizedkeyscommanduser none
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2
authorizedprincipalscommand none
authorizedprincipalscommanduser none
authorizedprincipalsfile none
banner none
casignaturealgorithms ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256
chrootdirectory none
ciphers +chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
clientalivecountmax 3
clientaliveinterval 0
compression yes
disableforwarding no
exposeauthinfo no
fingerprinthash SHA256
forcecommand none
gatewayports no
gssapiauthentication no
gssapicleanupcredentials yes
gssapikexalgorithms gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1-
gssapikeyexchange no
gssapistorecredentialsonrekey no
gssapistrictacceptorcheck yes
hostbasedacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256
hostbasedauthentication no
hostbasedusesnamefrompacketonly no
hostkeyagent none
hostkeyalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256
hostkey /etc/ssh/ssh_host_ecdsa_key
hostkey /etc/ssh/ssh_host_ed25519_key
hostkey /etc/ssh/ssh_host_rsa_key
ignorerhosts yes
ignoreuserknownhosts no
ipqos lowdelay throughput
kbdinteractiveauthentication no
kerberosauthentication no
kerberosorlocalpasswd yes
kerberosticketcleanup yes
kexalgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256
listenaddress 0.0.0.0:22
listenaddress [::]:22
logingracetime 120
loglevel INFO
macs ^umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
maxauthtries 6
maxsessions 10
maxstartups 10:30:100
modulifile /etc/ssh/moduli
passwordauthentication yes
permitemptypasswords no
permitlisten any
permitopen any
permitrootlogin without-password
permittty yes
permittunnel no
permituserenvironment no
permituserrc yes
persourcemaxstartups none
persourcenetblocksize 32:128
pidfile /run/sshd.pid
port 22
printlastlog yes
printmotd no
pubkeyacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256
pubkeyauthentication yes
pubkeyauthoptions none
rekeylimit 0 0
revokedkeys none
securitykeyprovider internal
streamlocalbindmask 0177
streamlocalbindunlink no
strictmodes yes
subsystem sftp /usr/lib/openssh/sftp-server
syslogfacility AUTH
tcpkeepalive yes
trustedusercakeys none
usedns no
usepam yes
versionaddendum none
x11displayoffset 10
x11forwarding yes
x11uselocalhost yes
xauthlocation /usr/bin/xauth

139
tests/fixtures/generic/sshd_config vendored Normal file
View File

@ -0,0 +1,139 @@
# $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication yes
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes
# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several
# problems.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation sandbox
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server