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 { PgSqlLock } from "@app/keystore/keystore";
|
||||
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 { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
|
||||
import { OrgServiceActor } from "@app/lib/types";
|
||||
@@ -439,92 +440,100 @@ export const gatewayV2ServiceFactory = ({
|
||||
throw new NotFoundError({ message: `Proxy ${proxyName} not found` });
|
||||
}
|
||||
|
||||
const [gateway] = await gatewayV2DAL.upsert(
|
||||
[
|
||||
{
|
||||
orgId,
|
||||
name,
|
||||
identityId: actorId,
|
||||
proxyId: proxy.id
|
||||
try {
|
||||
const [gateway] = await gatewayV2DAL.upsert(
|
||||
[
|
||||
{
|
||||
orgId,
|
||||
name,
|
||||
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"]
|
||||
);
|
||||
|
||||
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
|
||||
};
|
||||
} catch (err) {
|
||||
if (err instanceof DatabaseError && (err.error as { code: string })?.code === DatabaseErrorCode.UniqueViolation) {
|
||||
throw new BadRequestError({ message: `Gateway with name "${name}" already exists` });
|
||||
}
|
||||
};
|
||||
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
const heartbeat = async ({ orgPermission }: { orgPermission: OrgServiceActor }) => {
|
||||
|
||||
Reference in New Issue
Block a user