Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion electron/main/ipc-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
downloadModelFromHF,
} from './model-downloader'
import { getSettings, setSettings } from './settings-store'
import { checkSetupNeeded, markSetupDone, runFullSetup, getVenvPythonExe } from './python-setup'
import { checkSetupNeeded, markSetupDone, runFullSetup, getVenvPythonExe, ensureSslPatch } from './python-setup'
import { logger } from './logger'
import { getProcessRunner, getPythonProcessRunner, getExtPythonExe, terminateProcessRunner, terminateAllProcessRunners } from './process-runner'
import { getBuiltinExtensionsDir } from './builtin-sync'
Expand Down Expand Up @@ -71,6 +71,7 @@ function runExtensionSetup(
): Promise<void> {
return new Promise((resolve, reject) => {
const userData = app.getPath('userData')
ensureSslPatch(userData)
const pythonExe = getVenvPythonExe(userData)
const setupPy = join(extDir, 'setup.py')

Expand Down
29 changes: 29 additions & 0 deletions electron/main/python-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,35 @@ export function checkSetupNeeded(userData: string): boolean {
return false
}

/**
* Write a sitecustomize.py into the venv that silently skips malformed certs
* in the Windows certificate store (ssl.SSLError: [ASN1] nested asn1 error).
* Python imports sitecustomize automatically on every startup.
* No-op on non-Windows or if the patch already exists.
*/
export function ensureSslPatch(userData: string): void {
if (process.platform !== 'win32') return
const venvDir = getVenvDir(userData)
const sitePkg = join(venvDir, 'Lib', 'site-packages')
const target = join(sitePkg, 'sitecustomize.py')
if (!existsSync(sitePkg)) return
if (existsSync(target)) return
writeFileSync(target, [
'try:',
' import ssl as _ssl',
' _orig = _ssl.SSLContext._load_windows_store_certs',
' def _safe(self, storename, purpose):',
' try:',
' _orig(self, storename, purpose)',
' except _ssl.SSLError:',
' pass',
' _ssl.SSLContext._load_windows_store_certs = _safe',
'except Exception:',
' pass',
'',
].join('\n'), 'utf-8')
}

export function markSetupDone(userData: string): void {
writeFileSync(
join(userData, 'python_setup.json'),
Expand Down