This commit is contained in:
Joao Moreno 2017-06-28 15:53:00 +02:00
parent fcd9a8996a
commit 60efdae34c
2 changed files with 43 additions and 11 deletions

View file

@ -22,8 +22,8 @@ function main(argv: string[]): void {
return fatal('Wrong number of arguments');
}
if (!process.env['VSCODE_GIT_ASKPASS_PORT']) {
return fatal('Missing port');
if (!process.env['VSCODE_GIT_ASKPASS_HANDLE']) {
return fatal('Missing handle');
}
if (!process.env['VSCODE_GIT_ASKPASS_PIPE']) {
@ -35,13 +35,11 @@ function main(argv: string[]): void {
}
const output = process.env['VSCODE_GIT_ASKPASS_PIPE'];
const port = Number.parseInt(process.env['VSCODE_GIT_ASKPASS_PORT']);
const socketPath = process.env['VSCODE_GIT_ASKPASS_HANDLE'];
const request = argv[2];
const host = argv[4].substring(1, argv[4].length - 2);
const opts: http.RequestOptions = {
hostname: 'localhost',
port,
socketPath,
path: '/',
method: 'POST'
};

View file

@ -6,25 +6,59 @@
'use strict';
import { Disposable, window, InputBoxOptions } from 'vscode';
import { denodeify } from './util';
import * as path from 'path';
import * as http from 'http';
import * as os from 'os';
import * as crypto from 'crypto';
const randomBytes = denodeify<Buffer>(crypto.randomBytes);
export interface AskpassEnvironment {
GIT_ASKPASS: string;
ELECTRON_RUN_AS_NODE?: string;
VSCODE_GIT_ASKPASS_NODE?: string;
VSCODE_GIT_ASKPASS_MAIN?: string;
VSCODE_GIT_ASKPASS_HANDLE?: string;
}
function getIPCHandlePath(nonce: string): string {
if (process.platform === 'win32') {
return `\\\\.\\pipe\\vscode-git-askpass-${nonce}-sock`;
}
if (process.env['XDG_RUNTIME_DIR']) {
return path.join(process.env['XDG_RUNTIME_DIR'], `vscode-git-askpass-${nonce}.sock`);
}
return path.join(os.tmpdir(), `vscode-git-askpass-${nonce}.sock`);
}
export class Askpass implements Disposable {
private server: http.Server;
private portPromise: Promise<number>;
private ipcHandlePathPromise: Promise<string>;
private enabled = true;
constructor() {
this.server = http.createServer((req, res) => this.onRequest(req, res));
this.ipcHandlePathPromise = this.setup().catch(err => console.error(err));
}
private async setup(): Promise<string> {
const buffer = await randomBytes(20);
const nonce = buffer.toString('hex');
const ipcHandlePath = getIPCHandlePath(nonce);
try {
this.server.listen(0);
this.portPromise = new Promise<number>(c => this.server.on('listening', () => c(this.server.address().port)));
this.server.listen(ipcHandlePath);
this.server.on('error', err => console.error(err));
} catch (err) {
console.error('Could not launch git askpass helper.');
this.enabled = false;
}
return ipcHandlePath;
}
private onRequest(req: http.ServerRequest, res: http.ServerResponse): void {
@ -55,7 +89,7 @@ export class Askpass implements Disposable {
return await window.showInputBox(options) || '';
}
async getEnv(): Promise<any> {
async getEnv(): Promise<AskpassEnvironment> {
if (!this.enabled) {
return {
GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh')
@ -67,7 +101,7 @@ export class Askpass implements Disposable {
GIT_ASKPASS: path.join(__dirname, 'askpass.sh'),
VSCODE_GIT_ASKPASS_NODE: process.execPath,
VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js'),
VSCODE_GIT_ASKPASS_PORT: String(await this.portPromise)
VSCODE_GIT_ASKPASS_HANDLE: await this.ipcHandlePathPromise
};
}