Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 0 additions & 76 deletions packages/core/src/shared/lsp/utils/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ import { Logger, getLogger } from '../../logger/logger'
import { ChildProcess } from '../../utilities/processUtils'
import { waitUntil } from '../../utilities/timeoutUtils'
import { isDebugInstance } from '../../vscode/env'
import { tmpdir } from 'os'
import { join } from 'path'
import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports
import * as vscode from 'vscode'

export function getNodeExecutableName(): string {
return process.platform === 'win32' ? 'node.exe' : 'node'
Expand Down Expand Up @@ -85,53 +81,6 @@ export async function validateNodeExe(nodePath: string[], lsp: string, args: str
}
}

/**
* Gets proxy settings and certificates from VS Code
*/
export async function getVSCodeSettings(): Promise<{ proxyUrl?: string; certificatePath?: string }> {
const result: { proxyUrl?: string; certificatePath?: string } = {}
const logger = getLogger('amazonqLsp')

try {
// Get proxy settings from VS Code configuration
const httpConfig = vscode.workspace.getConfiguration('http')
const proxy = httpConfig.get<string>('proxy')
if (proxy) {
result.proxyUrl = proxy
logger.info(`Using proxy from VS Code settings: ${proxy}`)
}
} catch (err) {
logger.error(`Failed to get VS Code settings: ${err}`)
return result
}
try {
const tls = await import('tls')
// @ts-ignore Get system certificates
const systemCerts = tls.getCACertificates('system')
// @ts-ignore Get any existing extra certificates
const extraCerts = tls.getCACertificates('extra')
const allCerts = [...systemCerts, ...extraCerts]
if (allCerts && allCerts.length > 0) {
logger.info(`Found ${allCerts.length} certificates in system's trust store`)

const tempDir = join(tmpdir(), 'aws-toolkit-vscode')
if (!nodefs.existsSync(tempDir)) {
nodefs.mkdirSync(tempDir, { recursive: true })
}

const certPath = join(tempDir, 'vscode-ca-certs.pem')
const certContent = allCerts.join('\n')

nodefs.writeFileSync(certPath, certContent)
result.certificatePath = certPath
logger.info(`Created certificate file at: ${certPath}`)
}
} catch (err) {
logger.error(`Failed to extract certificates: ${err}`)
}
return result
}

export function createServerOptions({
encryptionKey,
executable,
Expand Down Expand Up @@ -160,31 +109,6 @@ export function createServerOptions({
Object.assign(processEnv, env)
}

// Get settings from VS Code
const settings = await getVSCodeSettings()
const logger = getLogger('amazonqLsp')

// Add proxy settings to the Node.js process
if (settings.proxyUrl) {
processEnv.HTTPS_PROXY = settings.proxyUrl
}

// Add certificate path if available
if (settings.certificatePath) {
processEnv.NODE_EXTRA_CA_CERTS = settings.certificatePath
logger.info(`Using certificate file: ${settings.certificatePath}`)
}

// Get SSL verification settings
const httpConfig = vscode.workspace.getConfiguration('http')
const strictSSL = httpConfig.get<boolean>('proxyStrictSSL', true)

// Handle SSL certificate verification
if (!strictSSL) {
processEnv.NODE_TLS_REJECT_UNAUTHORIZED = '0'
logger.info('SSL verification disabled via VS Code settings')
}

const lspProcess = new ChildProcess(bin, args, {
warnThresholds,
spawnOptions: {
Expand Down
71 changes: 67 additions & 4 deletions packages/core/src/shared/utilities/proxyUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@

import vscode from 'vscode'
import { getLogger } from '../logger/logger'
import { tmpdir } from 'os'
import { join } from 'path'
import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports

interface ProxyConfig {
proxyUrl: string | undefined
noProxy: string | undefined
proxyStrictSSL: boolean | true
certificateAuthority: string | undefined
}

Expand All @@ -23,11 +28,11 @@ export class ProxyUtil {
* See documentation here for setting the environement variables which are inherited by Flare LS process:
* https://github.com/aws/language-server-runtimes/blob/main/runtimes/docs/proxy.md
*/
public static configureProxyForLanguageServer(): void {
public static async configureProxyForLanguageServer(): Promise<void> {
try {
const proxyConfig = this.getProxyConfiguration()

this.setProxyEnvironmentVariables(proxyConfig)
await this.setProxyEnvironmentVariables(proxyConfig)
} catch (err) {
this.logger.error(`Failed to configure proxy: ${err}`)
}
Expand All @@ -41,21 +46,30 @@ export class ProxyUtil {
const proxyUrl = httpConfig.get<string>('proxy')
this.logger.debug(`Proxy URL Setting in VSCode Settings: ${proxyUrl}`)

const noProxy = httpConfig.get<string>('noProxy')
if (noProxy) {
this.logger.info(`Using noProxy from VS Code settings: ${noProxy}`)
}

const proxyStrictSSL = httpConfig.get<boolean>('proxyStrictSSL', true)

const amazonQConfig = vscode.workspace.getConfiguration('amazonQ')
const proxySettings = amazonQConfig.get<{
certificateAuthority?: string
}>('proxy', {})

return {
proxyUrl,
noProxy,
proxyStrictSSL,
certificateAuthority: proxySettings.certificateAuthority,
}
}

/**
* Sets environment variables based on proxy configuration
*/
private static setProxyEnvironmentVariables(config: ProxyConfig): void {
private static async setProxyEnvironmentVariables(config: ProxyConfig): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const proxyUrl = config.proxyUrl
// Set proxy environment variables
if (proxyUrl) {
Expand All @@ -64,11 +78,60 @@ export class ProxyUtil {
this.logger.debug(`Set proxy environment variables: ${proxyUrl}`)
}

// Set certificate bundle environment variables if configured
// set NO_PROXY vals
const noProxy = config.noProxy
if (noProxy) {
process.env.NO_PROXY = noProxy
this.logger.debug(`Set NO_PROXY environment variable: ${noProxy}`)
}

const strictSSL = config.proxyStrictSSL
// Handle SSL certificate verification
if (!strictSSL) {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
this.logger.info('SSL verification disabled via VS Code settings')
}

// Set certificate bundle environment variables if user configured
if (config.certificateAuthority) {
process.env.NODE_EXTRA_CA_CERTS = config.certificateAuthority
process.env.AWS_CA_BUNDLE = config.certificateAuthority
this.logger.debug(`Set certificate bundle path: ${config.certificateAuthority}`)
} else {
// Fallback to system certificates if no custom CA is configured
await this.setSystemCertificates()
}
}

/**
* Sets system certificates as fallback when no custom CA is configured
*/
private static async setSystemCertificates(): Promise<void> {
try {
const tls = await import('tls')
// @ts-ignore Get system certificates
const systemCerts = tls.getCACertificates('system')
// @ts-ignore Get any existing extra certificates
const extraCerts = tls.getCACertificates('extra')
const allCerts = [...systemCerts, ...extraCerts]
if (allCerts && allCerts.length > 0) {
this.logger.debug(`Found ${allCerts.length} certificates in system's trust store`)

const tempDir = join(tmpdir(), 'aws-toolkit-vscode')
if (!nodefs.existsSync(tempDir)) {
nodefs.mkdirSync(tempDir, { recursive: true })
}

const certPath = join(tempDir, 'vscode-ca-certs.pem')
const certContent = allCerts.join('\n')

nodefs.writeFileSync(certPath, certContent)
process.env.NODE_EXTRA_CA_CERTS = certPath
process.env.AWS_CA_BUNDLE = certPath
this.logger.debug(`Set system certificate bundle path: ${certPath}`)
}
} catch (err) {
this.logger.error(`Failed to extract system certificates: ${err}`)
}
}
}
Loading