diff --git a/packages/xo-server/src/api/host.mjs b/packages/xo-server/src/api/host.mjs index f4e68897871..46de69f2be5 100644 --- a/packages/xo-server/src/api/host.mjs +++ b/packages/xo-server/src/api/host.mjs @@ -4,6 +4,7 @@ import { createLogger } from '@xen-orchestra/log' import assert from 'assert' import { format } from 'json-rpc-peer' import { incorrectState } from 'xo-common/api-errors.js' +import { X509Certificate } from 'node:crypto' import backupGuard from './_backupGuard.mjs' @@ -530,6 +531,29 @@ setControlDomainMemory.resolve = { host: ['id', 'host', 'administrate'], } +// ------------------------------------------------------------------- + +export async function isPubKeyTooShort({ host }) { + const certificate = await this.getXapi(host).callAsync('host.get_server_certificate', host._xapiRef) + // begin and end of certificate need to be on separate lines for correct parsing + const correctedCertificate = certificate.replace(/(-----BEGIN CERTIFICATE-----)([^\n]+)/, '$1\n$2').replace(/([^\n]+)(-----END CERTIFICATE-----)/, '$1\n$2') + + const cert = new X509Certificate(correctedCertificate) + const isPubKeyTooShort = cert.publicKey.asymmetricKeyDetails.modulusLength < 2048 + console.log("====> isPubKeyTooShort :", isPubKeyTooShort, cert.publicKey.asymmetricKeyDetails.modulusLength) + return isPubKeyTooShort +} + +isPubKeyTooShort.description = 'get TLS key information' + +isPubKeyTooShort.params = { + id: { type: 'string' }, +} + +isPubKeyTooShort.resolve = { + host: ['id', 'host', 'view'], +} + // ------------------------------------------------------------------- /** * diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index da4d5756fbe..aae2c458fcf 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -1015,6 +1015,7 @@ const messages = { hostNoSupport: 'No XCP-ng Pro Support enabled on this host', hostSupportEnabled: 'XCP-ng Pro Support enabled on this host', noMoreMaintained: 'This host version is no longer maintained', + pubKeyTooShort: 'TLS key is too small to update to XCP-ng 8.3', // ----- Host actions ------ disableMaintenanceMode: 'Disable maintenance mode', diff --git a/packages/xo-web/src/common/xo/index.js b/packages/xo-web/src/common/xo/index.js index 8d0f5983fc7..17f2ad2e51f 100644 --- a/packages/xo-web/src/common/xo/index.js +++ b/packages/xo-web/src/common/xo/index.js @@ -1373,6 +1373,8 @@ export const installCertificateOnHost = (id, props) => _call('host.installCertif export const setControlDomainMemory = (id, memory) => _call('host.setControlDomainMemory', { id, memory }) +export const isPubKeyTooShort = (id) => _call('host.isPubKeyTooShort', { id }) + // for XCP-ng now export const installAllPatchesOnHost = ({ host }) => confirm({ diff --git a/packages/xo-web/src/xo-app/home/host-item.js b/packages/xo-web/src/xo-app/home/host-item.js index c802777d67b..0f671ce9a8a 100644 --- a/packages/xo-web/src/xo-app/home/host-item.js +++ b/packages/xo-web/src/xo-app/home/host-item.js @@ -16,6 +16,7 @@ import { editHost, fetchHostStats, isHostTimeConsistentWithXoaTime, + isPubKeyTooShort, removeTag, startHost, stopHost, @@ -37,6 +38,7 @@ import styles from './index.css' import BulkIcons from '../../common/bulk-icons' import { LICENSE_WARNING_BODY } from '../host/license-warning' +// import { LICENSE_WARNING_BODY } from '../host/license-warning' import { getXoaPlan, SOURCES } from '../../common/xoa-plans' @addSubscriptions({ @@ -44,6 +46,9 @@ import { getXoaPlan, SOURCES } from '../../common/xoa-plans' }) @connectStore(() => ({ container: createGetObject((_, props) => props.item.$pool), + isPubKeyTooShort: createSelector((_, props) => props.item.id, hostId => { + return isPubKeyTooShort(hostId) + }), needsRestart: createDoesHostNeedRestart((_, props) => props.item), nVms: createGetObjectsOfType('VM').count( createSelector( @@ -136,7 +141,7 @@ export default class HostItem extends Component { () => this.state.isHostTimeConsistentWithXoaTime, this._getAreHostsVersionsEqual, () => this.props.state.hostsByPoolId[this.props.item.$pool], - (needsRestart, host, isMaintained, isHostTimeConsistentWithXoaTime, areHostsVersionsEqual, poolHosts) => { + (needsRestart, host, isMaintained, isHostTimeConsistentWithXoaTime, isPubKeyTooShort, areHostsVersionsEqual, poolHosts) => { const alerts = [] if (needsRestart) { @@ -195,6 +200,33 @@ export default class HostItem extends Component { }) } + if (isPubKeyTooShort) { + console.log("=====> isPubKeyTooShort:", isPubKeyTooShort) + alerts.push({ + level: 'warning', + render: ( + + {_('pubKeyTooShort')} ( + + + {_('actionsRestricted')} + {' '} + {_('counterRestrictionsOptions')} + + + ) + + ), + }) + } + if (!host.hvmCapable) { alerts.push({ level: 'warning',