From 919eb83352da242bb43fbf8aebec26324e689865 Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Mon, 4 Feb 2019 12:48:17 -0700 Subject: [PATCH 1/3] Fix cert validation for authorized cluster endpoint on rke clusters rancher/rancher#16486 rancher/rancher#17793 --- app/components/cru-certificate/component.js | 31 ++--------------- .../cluster-driver/driver-rke/component.js | 30 +++++++++++++--- .../cluster-driver/driver-rke/template.hbs | 5 +-- lib/shared/addon/utils/util.js | 34 ++++++++++++++++--- 4 files changed, 61 insertions(+), 39 deletions(-) diff --git a/app/components/cru-certificate/component.js b/app/components/cru-certificate/component.js index 13a8f32af..0f457be35 100644 --- a/app/components/cru-certificate/component.js +++ b/app/components/cru-certificate/component.js @@ -4,16 +4,7 @@ import { inject as service } from '@ember/service'; import ViewNewEdit from 'shared/mixins/view-new-edit'; import OptionallyNamespaced from 'shared/mixins/optionally-namespaced'; import layout from './template'; - -const BEGIN_CERTIFICATE = [ - '-----BEGIN CERTIFICATE-----' -]; - -const BEGIN_KEY = [ - '-----BEGIN PRIVATE KEY-----', - '-----BEGIN EC PRIVATE KEY-----', - '-----BEGIN RSA PRIVATE KEY-----', -] +import { validateCertWeakly, validateKeyWeakly } from 'shared/utils/util'; export default Component.extend(ViewNewEdit, OptionallyNamespaced, { intl: service(), @@ -51,15 +42,7 @@ export default Component.extend(ViewNewEdit, OptionallyNamespaced, { const key = get(this, 'model.key'); if ( key ) { - let ok = false; - - BEGIN_KEY.forEach((prefix) => { - if ( key.trim().startsWith(prefix) ) { - ok = true; - } - }); - - if ( !ok ) { + if ( !validateKeyWeakly(key) ) { errors.push(intl.t('newCertificate.errors.key.invalidFormat')); } } else { @@ -69,15 +52,7 @@ export default Component.extend(ViewNewEdit, OptionallyNamespaced, { const certs = get(this, 'model.certs'); if ( certs ) { - let ok = false; - - BEGIN_CERTIFICATE.forEach((prefix) => { - if ( certs.trim().startsWith(prefix) ) { - ok = true; - } - }); - - if ( !ok ) { + if ( !validateCertWeakly(certs) ) { errors.push(intl.t('newCertificate.errors.cert.invalidFormat')); } } else { diff --git a/lib/shared/addon/components/cluster-driver/driver-rke/component.js b/lib/shared/addon/components/cluster-driver/driver-rke/component.js index 55a6eecbf..6fe1dc339 100644 --- a/lib/shared/addon/components/cluster-driver/driver-rke/component.js +++ b/lib/shared/addon/components/cluster-driver/driver-rke/component.js @@ -9,7 +9,7 @@ import { underlineToCamel, removeEmpty, keysToCamel, validateEndpoint, randomStr } from 'shared/utils/util'; import { validateHostname } from '@rancher/ember-api-store/utils/validate'; - +import { validateCertWeakly } from 'shared/utils/util'; import C from 'shared/utils/constants'; import YAML from 'yamljs'; import json2yaml from 'json2yaml'; @@ -436,8 +436,7 @@ export default InputTextFile.extend(ClusterDriver, { return out; }), - value: computed('pasteOrUpload', { - + yamlValue: computed('pasteOrUpload', { get() { const intl = get(this, 'intl'); @@ -536,7 +535,7 @@ export default InputTextFile.extend(ClusterDriver, { validate() { this._super(...arguments); - let errors = get(this, 'errors') || []; + let errors = []; let config = get(this, `cluster.rancherKubernetesEngineConfig`); if ( !get(this, 'isCustom') ) { @@ -561,6 +560,10 @@ export default InputTextFile.extend(ClusterDriver, { errors = this.validateEtcdService(errors); } + if ( get(this, 'cluster.localClusterAuthEndpoint.enabled') ) { + errors = this.validateAuthorizedClusterEndpoint(errors); + } + const clusterOptErrors = get(this, 'clusterOptErrors') || []; if ( get(config, 'cloudProvider.name') === 'azure' ) { @@ -578,6 +581,25 @@ export default InputTextFile.extend(ClusterDriver, { return errors.length === 0 && clusterOptErrors.length === 0; }, + validateAuthorizedClusterEndpoint(errors) { + let { localClusterAuthEndpoint } = get(this, 'cluster'); + let { caCerts, fqdn } = localClusterAuthEndpoint; + + if (caCerts) { + if (!validateCertWeakly(caCerts) ) { + errors.push(this.intl.t('newCertificate.errors.cert.invalidFormat')); + } + } else { + errors.push(this.intl.t('newCertificate.errors.cert.required')); + } + + if (fqdn) { + errors = validateHostname(fqdn, 'FQDN', get(this, 'intl'), { restricted: true }, errors); + } + + return errors; + }, + validateEtcdService(errors) { const etcdService = get(this, 'cluster.rancherKubernetesEngineConfig.services.etcd') || {}; const { creation, retention } = etcdService; diff --git a/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs b/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs index 82e45a4c1..59bc1dd7c 100644 --- a/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs +++ b/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs @@ -49,13 +49,13 @@ showDownload=false canChangeName=false autoResize=true - value=value + value=yamlValue }} {{copy-to-clipboard tooltipText="" buttonText="copyToClipboard.tooltip" - clipboardText=value + clipboardText=yamlValue class="with-clip" }} @@ -706,6 +706,7 @@ {{top-errors errors=clusterErrors}} {{top-errors errors=otherErrors}} {{top-errors errors=clusterOptErrors}} + {{#if (or isEdit (eq step 1))}} {{save-cancel createLabel=(if isCustom "saveCancel.next" "saveCancel.create") diff --git a/lib/shared/addon/utils/util.js b/lib/shared/addon/utils/util.js index 494cc3134..dba2933b2 100644 --- a/lib/shared/addon/utils/util.js +++ b/lib/shared/addon/utils/util.js @@ -162,11 +162,6 @@ export function absoluteUrl(url) { return parseUrl(url).href; } -export function validateEndpoint(str) { - // credit to https://stackoverflow.com/questions/4460586/javascript-regular-expression-to-check-for-ip-addresses - return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(str); -} - export function addAuthorization(url, user, pass) { url = absoluteUrl(url); var pos = url.indexOf('//'); @@ -481,6 +476,35 @@ export function deepCopy(obj) { return JSON.parse(JSON.stringify(obj)); } +export function validateEndpoint(str) { + // credit to https://stackoverflow.com/questions/4460586/javascript-regular-expression-to-check-for-ip-addresses + return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(str); +} + +export function validateCertWeakly(certs) { + const BEGIN_CERTIFICATE = [ + '-----BEGIN CERTIFICATE-----' + ]; + + return certs.trim().startsWith(BEGIN_CERTIFICATE[0]); +} + +export function validateKeyWeakly(key) { + const BEGIN_KEY = [ + '-----BEGIN PRIVATE KEY-----', + '-----BEGIN EC PRIVATE KEY-----', + '-----BEGIN RSA PRIVATE KEY-----', + ] + + BEGIN_KEY.forEach((prefix) => { + if ( key.trim().startsWith(prefix) ) { + return true; + } + }); + + return false; +} + var Util = { absoluteUrl, addAuthorization, From b7e576994704c978b0fa5852cb3fed6591a5932f Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Mon, 4 Feb 2019 14:26:39 -0700 Subject: [PATCH 2/3] Remove single auth provider warning rancher/rancher#17710 --- .../security/authentication/controller.js | 6 ------ .../security/authentication/template.hbs | 20 +++++++++++-------- translations/en-us.yaml | 1 - 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/global-admin/addon/security/authentication/controller.js b/lib/global-admin/addon/security/authentication/controller.js index d0d27608e..4752bbf12 100644 --- a/lib/global-admin/addon/security/authentication/controller.js +++ b/lib/global-admin/addon/security/authentication/controller.js @@ -77,12 +77,6 @@ export default Controller.extend({ ]; }), - showWarning: computed('filteredDrivers.[]', function() { - const providers = get(this, 'globalStore').all('authconfig').filterBy('enabled'); - - return providers.length > 1 ? true : false; - }), - filteredDrivers: computed(function() { // this is a soft disable of allowing multiple auth configs being active, we need to disable it right now but it will come back post 2.1 // when it does just itterate over the drivers again and remove filteredDrivers diff --git a/lib/global-admin/addon/security/authentication/template.hbs b/lib/global-admin/addon/security/authentication/template.hbs index 72dcf9e9b..b5e47ed0e 100644 --- a/lib/global-admin/addon/security/authentication/template.hbs +++ b/lib/global-admin/addon/security/authentication/template.hbs @@ -5,22 +5,26 @@ -{{#if showWarning}} - {{#banner-message color="bg-warning"}} - {{t "nav.admin.security.authWarning"}} - {{/banner-message}} -{{/if}}
diff --git a/translations/en-us.yaml b/translations/en-us.yaml index de1e40a61..dcf35782b 100644 --- a/translations/en-us.yaml +++ b/translations/en-us.yaml @@ -5322,6 +5322,7 @@ modalRestoreBackup: title: Restore From Backup backups: Available Backups error: A backup is required + fetching: Fetching new backups select: all: Select an available backup