diff options
-rw-r--r-- | .github/workflows/add-pr-labels.yml | 4 | ||||
-rw-r--r-- | .github/workflows/auto-author-assign.yml | 3 | ||||
-rw-r--r-- | .github/workflows/chceck-pr-message.yml | 4 | ||||
-rw-r--r-- | .github/workflows/check-pr-conflicts.yml | 2 | ||||
-rw-r--r-- | .github/workflows/check-stale.yml | 2 | ||||
-rw-r--r-- | .github/workflows/check-unused-imports.yml | 4 | ||||
-rw-r--r-- | .github/workflows/codeql.yml | 8 | ||||
-rw-r--r-- | .github/workflows/label-backport.yml | 2 | ||||
-rw-r--r-- | .github/workflows/linit-j2.yml | 19 | ||||
-rw-r--r-- | .github/workflows/repo-sync.yml | 17 | ||||
-rw-r--r-- | op-mode-definitions/generate-ipsec-profile.xml.in | 10 | ||||
-rw-r--r-- | op-mode-definitions/restart-ssh.xml.in | 2 | ||||
-rw-r--r-- | python/vyos/config_mgmt.py | 4 | ||||
-rw-r--r-- | python/vyos/ifconfig/macsec.py | 2 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_macsec.py | 8 | ||||
-rwxr-xr-x | src/conf_mode/interfaces_macsec.py | 10 | ||||
-rwxr-xr-x | src/op_mode/ikev2_profile_generator.py | 57 | ||||
-rwxr-xr-x | src/op_mode/powerctrl.py | 2 |
18 files changed, 82 insertions, 78 deletions
diff --git a/.github/workflows/add-pr-labels.yml b/.github/workflows/add-pr-labels.yml index ffb04f33b..24e8cc043 100644 --- a/.github/workflows/add-pr-labels.yml +++ b/.github/workflows/add-pr-labels.yml @@ -4,8 +4,6 @@ name: Add pull request labels on: pull_request_target: branches: - - current - - equuleus - sagitta permissions: @@ -14,5 +12,5 @@ permissions: jobs: add-pr-label: - uses: vyos/.github/.github/workflows/add-pr-labels.yml@feature/T6349-reusable-workflows + uses: vyos/.github/.github/workflows/add-pr-labels.yml@sagitta secrets: inherit diff --git a/.github/workflows/auto-author-assign.yml b/.github/workflows/auto-author-assign.yml index c3696ea47..0e65d4b59 100644 --- a/.github/workflows/auto-author-assign.yml +++ b/.github/workflows/auto-author-assign.yml @@ -3,12 +3,11 @@ on: pull_request_target: types: [opened, reopened, ready_for_review, locked] - permissions: pull-requests: write contents: read jobs: assign-author: - uses: vyos/.github/.github/workflows/assign-author.yml@feature/T6349-reusable-workflows + uses: vyos/.github/.github/workflows/assign-author.yml@sagitta secrets: inherit diff --git a/.github/workflows/chceck-pr-message.yml b/.github/workflows/chceck-pr-message.yml index b39b3724d..db050a6e5 100644 --- a/.github/workflows/chceck-pr-message.yml +++ b/.github/workflows/chceck-pr-message.yml @@ -4,9 +4,7 @@ name: Check pull request message format on: pull_request_target: branches: - - current - sagitta - - equuleus types: [opened, synchronize, edited] permissions: @@ -15,5 +13,5 @@ permissions: jobs: check-pr-title: - uses: vyos/.github/.github/workflows/check-pr-message.yml@feature/T6349-reusable-workflows + uses: vyos/.github/.github/workflows/check-pr-message.yml@sagitta secrets: inherit diff --git a/.github/workflows/check-pr-conflicts.yml b/.github/workflows/check-pr-conflicts.yml index 0c659e6ed..8a8e64c21 100644 --- a/.github/workflows/check-pr-conflicts.yml +++ b/.github/workflows/check-pr-conflicts.yml @@ -10,5 +10,5 @@ permissions: jobs: check-pr-conflict-call: - uses: vyos/.github/.github/workflows/check-pr-merge-conflict.yml@feature/T6349-reusable-workflows + uses: vyos/.github/.github/workflows/check-pr-merge-conflict.yml@sagitta secrets: inherit diff --git a/.github/workflows/check-stale.yml b/.github/workflows/check-stale.yml index 59d25a11b..11f440bbd 100644 --- a/.github/workflows/check-stale.yml +++ b/.github/workflows/check-stale.yml @@ -10,5 +10,5 @@ permissions: jobs: stale: - uses: vyos/.github/.github/workflows/check-stale.yml@feature/T6349-reusable-workflows + uses: vyos/.github/.github/workflows/check-stale.yml@sagitta secrets: inherit diff --git a/.github/workflows/check-unused-imports.yml b/.github/workflows/check-unused-imports.yml index 324a63e90..eccabc831 100644 --- a/.github/workflows/check-unused-imports.yml +++ b/.github/workflows/check-unused-imports.yml @@ -2,9 +2,7 @@ name: Check for unused imports using Pylint on: pull_request: branches: - - current - sagitta - - equuleus workflow_dispatch: permissions: @@ -12,5 +10,5 @@ permissions: jobs: check-unused-imports: - uses: vyos/.github/.github/workflows/check-unused-imports.yml@feature/T6349-reusable-workflows + uses: vyos/.github/.github/workflows/check-unused-imports.yml@sagitta secrets: inherit diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a4fc39e26..665cdda01 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,10 +2,12 @@ name: "Perform CodeQL Analysis" on: push: - branches: [ "current", "sagitta", "equuleus" ] + branches: + - sagitta pull_request: # The branches below must be a subset of the branches above - branches: [ "current" ] + branches: + - sagitta schedule: - cron: '22 10 * * 0' workflow_dispatch: @@ -17,7 +19,7 @@ permissions: jobs: codeql-analysis-call: - uses: vyos/.github/.github/workflows/codeql-analysis.yml@feature/T6349-reusable-workflows + uses: vyos/.github/.github/workflows/codeql-analysis.yml@sagitta secrets: inherit with: languages: "['python']" diff --git a/.github/workflows/label-backport.yml b/.github/workflows/label-backport.yml index 9192b8184..900155e7e 100644 --- a/.github/workflows/label-backport.yml +++ b/.github/workflows/label-backport.yml @@ -8,5 +8,5 @@ permissions: jobs: mergifyio-backport: - uses: vyos/.github/.github/workflows/label-backport.yml@feature/T6349-reusable-workflows + uses: vyos/.github/.github/workflows/label-backport.yml@sagitta secrets: inherit diff --git a/.github/workflows/linit-j2.yml b/.github/workflows/linit-j2.yml deleted file mode 100644 index 95bfa61f0..000000000 --- a/.github/workflows/linit-j2.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: J2 Lint - -on: - pull_request: - branches: - - current - - sagitta - - equuleus - workflow_dispatch: - -permissions: - pull-requests: write - contents: read - -jobs: - j2lint: - uses: vyos/.github/.github/workflows/lint-j2.yml@feature/T6349-reusable-workflows - secrets: inherit diff --git a/.github/workflows/repo-sync.yml b/.github/workflows/repo-sync.yml new file mode 100644 index 000000000..b475a84ec --- /dev/null +++ b/.github/workflows/repo-sync.yml @@ -0,0 +1,17 @@ +name: Repo-sync + +on: + pull_request_target: + types: + - closed + branches: + - sagitta + workflow_dispatch: + +jobs: + trigger-sync: + uses: vyos/.github/.github/workflows/trigger-repo-sync.yml@sagitta + secrets: + REMOTE_REPO: ${{ secrets.REMOTE_REPO }} + REMOTE_OWNER: ${{ secrets.REMOTE_OWNER }} + PAT: ${{ secrets.PAT }} diff --git a/op-mode-definitions/generate-ipsec-profile.xml.in b/op-mode-definitions/generate-ipsec-profile.xml.in index b7203d7d1..afa299da2 100644 --- a/op-mode-definitions/generate-ipsec-profile.xml.in +++ b/op-mode-definitions/generate-ipsec-profile.xml.in @@ -28,7 +28,7 @@ <script>${vyos_completion_dir}/list_local_ips.sh --both</script> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7"</command> + <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7"</command> <children> <tagNode name="name"> <properties> @@ -37,7 +37,7 @@ <list><name></list> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --name "$9"</command> + <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --name "$9"</command> <children> <tagNode name="profile"> <properties> @@ -46,7 +46,7 @@ <list><name></list> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --name "$9" --profile "${11}"</command> + <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --name "$9" --profile "${11}"</command> </tagNode> </children> </tagNode> @@ -57,7 +57,7 @@ <list><name></list> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --profile "$9"</command> + <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --profile "$9"</command> <children> <tagNode name="name"> <properties> @@ -66,7 +66,7 @@ <list><name></list> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --profile "$9" --name "${11}"</command> + <command>sudo ${vyos_op_scripts_dir}/ikev2_profile_generator.py --os ios --connection "$5" --remote "$7" --profile "$9" --name "${11}"</command> </tagNode> </children> </tagNode> diff --git a/op-mode-definitions/restart-ssh.xml.in b/op-mode-definitions/restart-ssh.xml.in index 6504cc18a..543cafc24 100644 --- a/op-mode-definitions/restart-ssh.xml.in +++ b/op-mode-definitions/restart-ssh.xml.in @@ -6,7 +6,7 @@ <properties> <help>Restart SSH service</help> </properties> - <command>if cli-shell-api existsActive service ssh; then sudo systemctl restart ssh.service; else echo "Service SSH not configured"; fi</command> + <command>if cli-shell-api existsActive service ssh; then sudo systemctl restart "ssh@*.service"; else echo "Service SSH not configured"; fi</command> </node> </children> </node> diff --git a/python/vyos/config_mgmt.py b/python/vyos/config_mgmt.py index 70b6ea203..d518737ca 100644 --- a/python/vyos/config_mgmt.py +++ b/python/vyos/config_mgmt.py @@ -81,9 +81,11 @@ def save_config(target, json_out=None): if rc != 0: logger.critical(f'save config failed: {out}') -def unsaved_commits() -> bool: +def unsaved_commits(allow_missing_config=False) -> bool: if get_full_version_data()['boot_via'] == 'livecd': return False + if allow_missing_config and not os.path.exists(config_file): + return True tmp_save = '/tmp/config.running' save_config(tmp_save) ret = not cmp(tmp_save, config_file, shallow=False) diff --git a/python/vyos/ifconfig/macsec.py b/python/vyos/ifconfig/macsec.py index bde1d9aec..383905814 100644 --- a/python/vyos/ifconfig/macsec.py +++ b/python/vyos/ifconfig/macsec.py @@ -66,7 +66,7 @@ class MACsecIf(Interface): cmd = 'ip macsec add {ifname} rx port 1 address'.format(**self.config) cmd += f' {peer_config["mac"]}' self._cmd(cmd) - # Add the rx-key to the address + # Add the encryption key to the address cmd += f' sa 0 pn 1 on key 01 {peer_config["key"]}' self._cmd(cmd) diff --git a/smoketest/scripts/cli/test_interfaces_macsec.py b/smoketest/scripts/cli/test_interfaces_macsec.py index a4e6840ca..d73895b7f 100755 --- a/smoketest/scripts/cli/test_interfaces_macsec.py +++ b/smoketest/scripts/cli/test_interfaces_macsec.py @@ -225,11 +225,11 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase): self.cli_commit() self.cli_delete(self._base_path + [interface, 'security', 'mka']) - # check validate() - tx-key required + # check validate() - key required with self.assertRaises(ConfigSessionError): self.cli_commit() - # check validate() - tx-key length must match cipher + # check validate() - key length must match cipher self.cli_set(self._base_path + [interface, 'security', 'static', 'key', tx_key_2]) with self.assertRaises(ConfigSessionError): self.cli_commit() @@ -239,7 +239,7 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase): with self.assertRaises(ConfigSessionError): self.cli_commit() - # check validate() - enabled peer must have both rx-key and MAC defined + # check validate() - enabled peer must have both key and MAC defined self.cli_set(self._base_path + [interface, 'security', 'static', 'peer', 'TESTPEER']) with self.assertRaises(ConfigSessionError): self.cli_commit() @@ -252,7 +252,7 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase): self.cli_commit() self.cli_set(self._base_path + [interface, 'security', 'static', 'peer', 'TESTPEER', 'mac', peer_mac]) - # check validate() - peer rx-key length must match cipher + # check validate() - peer key length must match cipher self.cli_set(self._base_path + [interface, 'security', 'cipher', cipher2]) self.cli_set(self._base_path + [interface, 'security', 'static', 'key', tx_key_2]) with self.assertRaises(ConfigSessionError): diff --git a/src/conf_mode/interfaces_macsec.py b/src/conf_mode/interfaces_macsec.py index eb0ca9a8b..3ede4377a 100755 --- a/src/conf_mode/interfaces_macsec.py +++ b/src/conf_mode/interfaces_macsec.py @@ -103,9 +103,9 @@ def verify(macsec): # Logic to check static configuration if dict_search('security.static', macsec) != None: - # tx-key must be defined + # key must be defined if dict_search('security.static.key', macsec) == None: - raise ConfigError('Static MACsec tx-key must be defined.') + raise ConfigError('Static MACsec key must be defined.') tx_len = len(dict_search('security.static.key', macsec)) @@ -119,12 +119,12 @@ def verify(macsec): if 'peer' not in macsec['security']['static']: raise ConfigError('Must have at least one peer defined for static MACsec') - # For every enabled peer, make sure a MAC and rx-key is defined + # For every enabled peer, make sure a MAC and key is defined for peer, peer_config in macsec['security']['static']['peer'].items(): if 'disable' not in peer_config and ('mac' not in peer_config or 'key' not in peer_config): - raise ConfigError('Every enabled MACsec static peer must have a MAC address and rx-key defined.') + raise ConfigError('Every enabled MACsec static peer must have a MAC address and key defined!') - # check rx-key length against cipher suite + # check key length against cipher suite rx_len = len(peer_config['key']) if dict_search('security.cipher', macsec) == 'gcm-aes-128' and rx_len != GCM_AES_128_LEN: diff --git a/src/op_mode/ikev2_profile_generator.py b/src/op_mode/ikev2_profile_generator.py index 169a15840..b193d8109 100755 --- a/src/op_mode/ikev2_profile_generator.py +++ b/src/op_mode/ikev2_profile_generator.py @@ -21,6 +21,7 @@ from socket import getfqdn from cryptography.x509.oid import NameOID from vyos.configquery import ConfigTreeQuery +from vyos.config import config_dict_mangle_acme from vyos.pki import CERT_BEGIN from vyos.pki import CERT_END from vyos.pki import find_chain @@ -123,6 +124,8 @@ pki_base = ['pki'] conf = ConfigTreeQuery() if not conf.exists(config_base): exit('IPsec remote-access is not configured!') +if not conf.exists(pki_base): + exit('PKI is not configured!') profile_name = 'VyOS IKEv2 Profile' if args.profile: @@ -147,30 +150,36 @@ tmp = getfqdn().split('.') tmp = reversed(tmp) data['rfqdn'] = '.'.join(tmp) -pki = conf.get_config_dict(pki_base, get_first_key=True) -cert_name = data['authentication']['x509']['certificate'] - -cert_data = load_certificate(pki['certificate'][cert_name]['certificate']) -data['cert_common_name'] = cert_data.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value -data['ca_common_name'] = cert_data.issuer.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value -data['ca_certificates'] = [] - -loaded_ca_certs = {load_certificate(c['certificate']) - for c in pki['ca'].values()} if 'ca' in pki else {} - -for ca_name in data['authentication']['x509']['ca_certificate']: - loaded_ca_cert = load_certificate(pki['ca'][ca_name]['certificate']) - ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs) - for ca in ca_full_chain: - tmp = { - 'ca_name' : ca.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value, - 'ca_chain' : encode_certificate(ca).replace(CERT_BEGIN, '').replace(CERT_END, '').replace('\n', ''), - } - data['ca_certificates'].append(tmp) - -# Remove duplicate list entries for CA certificates, as they are added by their common name -# https://stackoverflow.com/a/9427216 -data['ca_certificates'] = [dict(t) for t in {tuple(d.items()) for d in data['ca_certificates']}] +if args.os == 'ios': + pki = conf.get_config_dict(pki_base, get_first_key=True) + if 'certificate' in pki: + for certificate in pki['certificate']: + pki['certificate'][certificate] = config_dict_mangle_acme(certificate, pki['certificate'][certificate]) + + cert_name = data['authentication']['x509']['certificate'] + + + cert_data = load_certificate(pki['certificate'][cert_name]['certificate']) + data['cert_common_name'] = cert_data.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value + data['ca_common_name'] = cert_data.issuer.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value + data['ca_certificates'] = [] + + loaded_ca_certs = {load_certificate(c['certificate']) + for c in pki['ca'].values()} if 'ca' in pki else {} + + for ca_name in data['authentication']['x509']['ca_certificate']: + loaded_ca_cert = load_certificate(pki['ca'][ca_name]['certificate']) + ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs) + for ca in ca_full_chain: + tmp = { + 'ca_name' : ca.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value, + 'ca_chain' : encode_certificate(ca).replace(CERT_BEGIN, '').replace(CERT_END, '').replace('\n', ''), + } + data['ca_certificates'].append(tmp) + + # Remove duplicate list entries for CA certificates, as they are added by their common name + # https://stackoverflow.com/a/9427216 + data['ca_certificates'] = [dict(t) for t in {tuple(d.items()) for d in data['ca_certificates']}] esp_proposals = conf.get_config_dict(ipsec_base + ['esp-group', data['esp_group'], 'proposal'], key_mangling=('-', '_'), get_first_key=True) diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py index 6c8f802b5..cb4a175dd 100755 --- a/src/op_mode/powerctrl.py +++ b/src/op_mode/powerctrl.py @@ -110,7 +110,7 @@ def check_unsaved_config(): from vyos.config_mgmt import unsaved_commits from vyos.utils.boot import boot_configuration_success - if unsaved_commits() and boot_configuration_success(): + if unsaved_commits(allow_missing_config=True) and boot_configuration_success(): print("Warning: there are unsaved configuration changes!") print("Run 'save' command if you do not want to lose those changes after reboot/shutdown.") else: |