mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-22 07:00:22 -05:00
fix(https-proxy): add error handling when using cached cert (#17628)
This commit is contained in:
@@ -20,7 +20,6 @@ const {
|
||||
const generateKeyPairAsync = Promise.promisify(pki.rsa.generateKeyPair)
|
||||
|
||||
const ipAddressRe = /^[\d\.]+$/
|
||||
const asterisksRe = /\*/g
|
||||
|
||||
const CAattrs = [{
|
||||
name: 'commonName',
|
||||
@@ -119,6 +118,10 @@ const ServerExtensions = [{
|
||||
name: 'subjectKeyIdentifier',
|
||||
}]
|
||||
|
||||
function hostnameToFilename (hostname) {
|
||||
return hostname.replace(/\*/g, '_')
|
||||
}
|
||||
|
||||
class CA {
|
||||
constructor (caFolder) {
|
||||
if (!caFolder) {
|
||||
@@ -167,9 +170,9 @@ class CA {
|
||||
this.CAkeys = keys
|
||||
|
||||
return Promise.all([
|
||||
fs.outputFileAsync(path.join(this.certsFolder, 'ca.pem'), pki.certificateToPem(cert)),
|
||||
fs.outputFileAsync(path.join(this.keysFolder, 'ca.private.key'), pki.privateKeyToPem(keys.privateKey)),
|
||||
fs.outputFileAsync(path.join(this.keysFolder, 'ca.public.key'), pki.publicKeyToPem(keys.publicKey)),
|
||||
fs.outputFileAsync(this.getCACertPath(), pki.certificateToPem(cert)),
|
||||
fs.outputFileAsync(this.getCAPrivateKeyPath(), pki.privateKeyToPem(keys.privateKey)),
|
||||
fs.outputFileAsync(this.getCAPublicKeyPath(), pki.publicKeyToPem(keys.publicKey)),
|
||||
this.writeCAVersion(),
|
||||
])
|
||||
})
|
||||
@@ -177,9 +180,9 @@ class CA {
|
||||
|
||||
loadCA () {
|
||||
return Promise.props({
|
||||
certPEM: fs.readFileAsync(path.join(this.certsFolder, 'ca.pem'), 'utf-8'),
|
||||
keyPrivatePEM: fs.readFileAsync(path.join(this.keysFolder, 'ca.private.key'), 'utf-8'),
|
||||
keyPublicPEM: fs.readFileAsync(path.join(this.keysFolder, 'ca.public.key'), 'utf-8'),
|
||||
certPEM: fs.readFileAsync(this.getCACertPath(), 'utf-8'),
|
||||
keyPrivatePEM: fs.readFileAsync(this.getCAPrivateKeyPath(), 'utf-8'),
|
||||
keyPublicPEM: fs.readFileAsync(this.getCAPublicKeyPath(), 'utf-8'),
|
||||
})
|
||||
.then((results) => {
|
||||
this.CAcert = pki.certificateFromPem(results.certPEM)
|
||||
@@ -231,29 +234,59 @@ class CA {
|
||||
const keyPrivatePem = pki.privateKeyToPem(keysServer.privateKey)
|
||||
const keyPublicPem = pki.publicKeyToPem(keysServer.publicKey)
|
||||
|
||||
const dest = mainHost.replace(asterisksRe, '_')
|
||||
const baseFilename = hostnameToFilename(mainHost)
|
||||
|
||||
return Promise.all([
|
||||
fs.outputFileAsync(path.join(this.certsFolder, `${dest}.pem`), certPem),
|
||||
fs.outputFileAsync(path.join(this.keysFolder, `${dest}.key`), keyPrivatePem),
|
||||
fs.outputFileAsync(path.join(this.keysFolder, `${dest}.public.key`), keyPublicPem),
|
||||
fs.outputFileAsync(this.getCertPath(baseFilename), certPem),
|
||||
fs.outputFileAsync(this.getPrivateKeyPath(baseFilename), keyPrivatePem),
|
||||
fs.outputFileAsync(this.getPublicKeyPath(baseFilename), keyPublicPem),
|
||||
])
|
||||
.return([certPem, keyPrivatePem])
|
||||
}
|
||||
|
||||
getCertificateKeysForHostname (hostname) {
|
||||
const dest = hostname.replace(asterisksRe, '_')
|
||||
clearDataForHostname (hostname) {
|
||||
const baseFilename = hostnameToFilename(hostname)
|
||||
|
||||
return Promise.all([
|
||||
fs.readFileAsync(path.join(this.certsFolder, `${dest}.pem`)),
|
||||
fs.readFileAsync(path.join(this.keysFolder, `${dest}.key`)),
|
||||
fs.remove(this.getCertPath(baseFilename)),
|
||||
fs.remove(this.getPrivateKeyPath(baseFilename)),
|
||||
fs.remove(this.getPublicKeyPath(baseFilename)),
|
||||
])
|
||||
}
|
||||
|
||||
getCertificateKeysForHostname (hostname) {
|
||||
const baseFilename = hostnameToFilename(hostname)
|
||||
|
||||
return Promise.all([
|
||||
fs.readFileAsync(this.getCertPath(baseFilename)),
|
||||
fs.readFileAsync(this.getPrivateKeyPath(baseFilename)),
|
||||
])
|
||||
}
|
||||
|
||||
getPrivateKeyPath (baseFilename) {
|
||||
return path.join(this.keysFolder, `${baseFilename}.key`)
|
||||
}
|
||||
|
||||
getPublicKeyPath (baseFilename) {
|
||||
return path.join(this.keysFolder, `${baseFilename}.public.key`)
|
||||
}
|
||||
|
||||
getCertPath (baseFilename) {
|
||||
return path.join(this.certsFolder, `${baseFilename}.pem`)
|
||||
}
|
||||
|
||||
getCACertPath () {
|
||||
return path.join(this.certsFolder, 'ca.pem')
|
||||
}
|
||||
|
||||
getCAPrivateKeyPath () {
|
||||
return path.join(this.keysFolder, 'ca.private.key')
|
||||
}
|
||||
|
||||
getCAPublicKeyPath () {
|
||||
return path.join(this.keysFolder, 'ca.public.key')
|
||||
}
|
||||
|
||||
getCAVersionPath () {
|
||||
return path.join(this.baseCAFolder, 'ca_version.txt')
|
||||
}
|
||||
@@ -286,7 +319,7 @@ class CA {
|
||||
static create (caFolder) {
|
||||
const ca = new CA(caFolder)
|
||||
|
||||
return fs.statAsync(path.join(ca.certsFolder, 'ca.pem'))
|
||||
return fs.statAsync(ca.getCACertPath())
|
||||
.bind(ca)
|
||||
.then(ca.assertMinimumCAVersion)
|
||||
.tapCatch(ca.removeAll)
|
||||
|
||||
@@ -183,6 +183,15 @@ class Server {
|
||||
}
|
||||
|
||||
return this._getPortFor(hostname)
|
||||
.catch(async (err) => {
|
||||
debug('Error adding context, deleting certs and regenning %o', { hostname, err })
|
||||
|
||||
// files on disk can be corrupted, so try again
|
||||
// @see https://github.com/cypress-io/cypress/issues/8705
|
||||
await this._ca.clearDataForHostname(hostname)
|
||||
|
||||
return this._getPortFor(hostname)
|
||||
})
|
||||
.then((port) => {
|
||||
sslServers[hostname] = { port }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user