mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
misc: added proper handling for gateway name conflicts
This commit is contained in:
@@ -6,7 +6,8 @@ import * as x509 from "@peculiar/x509";
|
|||||||
import { TProxies } from "@app/db/schemas";
|
import { TProxies } from "@app/db/schemas";
|
||||||
import { PgSqlLock } from "@app/keystore/keystore";
|
import { PgSqlLock } from "@app/keystore/keystore";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { DatabaseErrorCode } from "@app/lib/error-codes";
|
||||||
|
import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors";
|
||||||
import { GatewayProxyProtocol } from "@app/lib/gateway/types";
|
import { GatewayProxyProtocol } from "@app/lib/gateway/types";
|
||||||
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
|
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
|
||||||
import { OrgServiceActor } from "@app/lib/types";
|
import { OrgServiceActor } from "@app/lib/types";
|
||||||
@@ -439,92 +440,100 @@ export const gatewayV2ServiceFactory = ({
|
|||||||
throw new NotFoundError({ message: `Proxy ${proxyName} not found` });
|
throw new NotFoundError({ message: `Proxy ${proxyName} not found` });
|
||||||
}
|
}
|
||||||
|
|
||||||
const [gateway] = await gatewayV2DAL.upsert(
|
try {
|
||||||
[
|
const [gateway] = await gatewayV2DAL.upsert(
|
||||||
{
|
[
|
||||||
orgId,
|
{
|
||||||
name,
|
orgId,
|
||||||
identityId: actorId,
|
name,
|
||||||
proxyId: proxy.id
|
identityId: actorId,
|
||||||
|
proxyId: proxy.id
|
||||||
|
}
|
||||||
|
],
|
||||||
|
["identityId"]
|
||||||
|
);
|
||||||
|
|
||||||
|
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
|
||||||
|
const gatewayServerCaCert = new x509.X509Certificate(orgCAs.gatewayServerCaCertificate);
|
||||||
|
const rootGatewayCaCert = new x509.X509Certificate(orgCAs.rootGatewayCaCertificate);
|
||||||
|
const gatewayClientCaCert = new x509.X509Certificate(orgCAs.gatewayClientCaCertificate);
|
||||||
|
|
||||||
|
const gatewayServerCaSkObj = crypto.nativeCrypto.createPrivateKey({
|
||||||
|
key: orgCAs.gatewayServerCaPrivateKey,
|
||||||
|
format: "der",
|
||||||
|
type: "pkcs8"
|
||||||
|
});
|
||||||
|
const gatewayServerCaPrivateKey = await crypto.nativeCrypto.subtle.importKey(
|
||||||
|
"pkcs8",
|
||||||
|
gatewayServerCaSkObj.export({ format: "der", type: "pkcs8" }),
|
||||||
|
alg,
|
||||||
|
true,
|
||||||
|
["sign"]
|
||||||
|
);
|
||||||
|
|
||||||
|
const gatewayServerKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||||
|
const gatewayServerCertIssuedAt = new Date();
|
||||||
|
const gatewayServerCertExpireAt = new Date(new Date().setMonth(new Date().getMonth() + 1));
|
||||||
|
const gatewayServerCertPrivateKey = crypto.nativeCrypto.KeyObject.from(gatewayServerKeys.privateKey);
|
||||||
|
|
||||||
|
const gatewayServerCertExtensions: x509.Extension[] = [
|
||||||
|
new x509.BasicConstraintsExtension(false),
|
||||||
|
await x509.AuthorityKeyIdentifierExtension.create(gatewayServerCaCert, false),
|
||||||
|
await x509.SubjectKeyIdentifierExtension.create(gatewayServerKeys.publicKey),
|
||||||
|
new x509.CertificatePolicyExtension(["2.5.29.32.0"]), // anyPolicy
|
||||||
|
new x509.KeyUsagesExtension(
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
x509.KeyUsageFlags[CertKeyUsage.DIGITAL_SIGNATURE] | x509.KeyUsageFlags[CertKeyUsage.KEY_ENCIPHERMENT],
|
||||||
|
true
|
||||||
|
),
|
||||||
|
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.SERVER_AUTH]], true),
|
||||||
|
new x509.SubjectAlternativeNameExtension([
|
||||||
|
{ type: "dns", value: "localhost" },
|
||||||
|
{ type: "ip", value: "127.0.0.1" },
|
||||||
|
{ type: "ip", value: "::1" }
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
const gatewayServerSerialNumber = createSerialNumber();
|
||||||
|
const gatewayServerCertificate = await x509.X509CertificateGenerator.create({
|
||||||
|
serialNumber: gatewayServerSerialNumber,
|
||||||
|
subject: `O=${orgId},CN=Gateway`,
|
||||||
|
issuer: gatewayServerCaCert.subject,
|
||||||
|
notBefore: gatewayServerCertIssuedAt,
|
||||||
|
notAfter: gatewayServerCertExpireAt,
|
||||||
|
signingKey: gatewayServerCaPrivateKey,
|
||||||
|
publicKey: gatewayServerKeys.publicKey,
|
||||||
|
signingAlgorithm: alg,
|
||||||
|
extensions: gatewayServerCertExtensions
|
||||||
|
});
|
||||||
|
|
||||||
|
const proxyCredentials = await proxyService.getCredentialsForGateway({
|
||||||
|
proxyName,
|
||||||
|
orgId,
|
||||||
|
gatewayId: gateway.id
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
gatewayId: gateway.id,
|
||||||
|
proxyIp: proxyCredentials.proxyIp,
|
||||||
|
pki: {
|
||||||
|
serverCertificate: gatewayServerCertificate.toString("pem"),
|
||||||
|
serverPrivateKey: gatewayServerCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
|
||||||
|
clientCertificateChain: constructPemChainFromCerts([gatewayClientCaCert, rootGatewayCaCert])
|
||||||
|
},
|
||||||
|
ssh: {
|
||||||
|
clientCertificate: proxyCredentials.clientSshCert,
|
||||||
|
clientPrivateKey: proxyCredentials.clientSshPrivateKey,
|
||||||
|
serverCAPublicKey: proxyCredentials.serverCAPublicKey
|
||||||
}
|
}
|
||||||
],
|
};
|
||||||
["identityId"]
|
} catch (err) {
|
||||||
);
|
if (err instanceof DatabaseError && (err.error as { code: string })?.code === DatabaseErrorCode.UniqueViolation) {
|
||||||
|
throw new BadRequestError({ message: `Gateway with name "${name}" already exists` });
|
||||||
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
|
|
||||||
const gatewayServerCaCert = new x509.X509Certificate(orgCAs.gatewayServerCaCertificate);
|
|
||||||
const rootGatewayCaCert = new x509.X509Certificate(orgCAs.rootGatewayCaCertificate);
|
|
||||||
const gatewayClientCaCert = new x509.X509Certificate(orgCAs.gatewayClientCaCertificate);
|
|
||||||
|
|
||||||
const gatewayServerCaSkObj = crypto.nativeCrypto.createPrivateKey({
|
|
||||||
key: orgCAs.gatewayServerCaPrivateKey,
|
|
||||||
format: "der",
|
|
||||||
type: "pkcs8"
|
|
||||||
});
|
|
||||||
const gatewayServerCaPrivateKey = await crypto.nativeCrypto.subtle.importKey(
|
|
||||||
"pkcs8",
|
|
||||||
gatewayServerCaSkObj.export({ format: "der", type: "pkcs8" }),
|
|
||||||
alg,
|
|
||||||
true,
|
|
||||||
["sign"]
|
|
||||||
);
|
|
||||||
|
|
||||||
const gatewayServerKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
|
||||||
const gatewayServerCertIssuedAt = new Date();
|
|
||||||
const gatewayServerCertExpireAt = new Date(new Date().setMonth(new Date().getMonth() + 1));
|
|
||||||
const gatewayServerCertPrivateKey = crypto.nativeCrypto.KeyObject.from(gatewayServerKeys.privateKey);
|
|
||||||
|
|
||||||
const gatewayServerCertExtensions: x509.Extension[] = [
|
|
||||||
new x509.BasicConstraintsExtension(false),
|
|
||||||
await x509.AuthorityKeyIdentifierExtension.create(gatewayServerCaCert, false),
|
|
||||||
await x509.SubjectKeyIdentifierExtension.create(gatewayServerKeys.publicKey),
|
|
||||||
new x509.CertificatePolicyExtension(["2.5.29.32.0"]), // anyPolicy
|
|
||||||
new x509.KeyUsagesExtension(
|
|
||||||
// eslint-disable-next-line no-bitwise
|
|
||||||
x509.KeyUsageFlags[CertKeyUsage.DIGITAL_SIGNATURE] | x509.KeyUsageFlags[CertKeyUsage.KEY_ENCIPHERMENT],
|
|
||||||
true
|
|
||||||
),
|
|
||||||
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.SERVER_AUTH]], true),
|
|
||||||
new x509.SubjectAlternativeNameExtension([
|
|
||||||
{ type: "dns", value: "localhost" },
|
|
||||||
{ type: "ip", value: "127.0.0.1" },
|
|
||||||
{ type: "ip", value: "::1" }
|
|
||||||
])
|
|
||||||
];
|
|
||||||
|
|
||||||
const gatewayServerSerialNumber = createSerialNumber();
|
|
||||||
const gatewayServerCertificate = await x509.X509CertificateGenerator.create({
|
|
||||||
serialNumber: gatewayServerSerialNumber,
|
|
||||||
subject: `O=${orgId},CN=Gateway`,
|
|
||||||
issuer: gatewayServerCaCert.subject,
|
|
||||||
notBefore: gatewayServerCertIssuedAt,
|
|
||||||
notAfter: gatewayServerCertExpireAt,
|
|
||||||
signingKey: gatewayServerCaPrivateKey,
|
|
||||||
publicKey: gatewayServerKeys.publicKey,
|
|
||||||
signingAlgorithm: alg,
|
|
||||||
extensions: gatewayServerCertExtensions
|
|
||||||
});
|
|
||||||
|
|
||||||
const proxyCredentials = await proxyService.getCredentialsForGateway({
|
|
||||||
proxyName,
|
|
||||||
orgId,
|
|
||||||
gatewayId: gateway.id
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
gatewayId: gateway.id,
|
|
||||||
proxyIp: proxyCredentials.proxyIp,
|
|
||||||
pki: {
|
|
||||||
serverCertificate: gatewayServerCertificate.toString("pem"),
|
|
||||||
serverPrivateKey: gatewayServerCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
|
|
||||||
clientCertificateChain: constructPemChainFromCerts([gatewayClientCaCert, rootGatewayCaCert])
|
|
||||||
},
|
|
||||||
ssh: {
|
|
||||||
clientCertificate: proxyCredentials.clientSshCert,
|
|
||||||
clientPrivateKey: proxyCredentials.clientSshPrivateKey,
|
|
||||||
serverCAPublicKey: proxyCredentials.serverCAPublicKey
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const heartbeat = async ({ orgPermission }: { orgPermission: OrgServiceActor }) => {
|
const heartbeat = async ({ orgPermission }: { orgPermission: OrgServiceActor }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user