diff --git a/package.json b/package.json
index 50f3e1dc6..c351a7eae 100644
--- a/package.json
+++ b/package.json
@@ -349,9 +349,9 @@
"default": "8005",
"description": "Port to connect to IBM i Debug Service."
},
- "debugSecure": {
+ "debugIsSecure": {
"type": "boolean",
- "default": true,
+ "default": false,
"description": "Used to determine if the client should connect securely or not."
},
"debugUpdateProductionFiles": {
@@ -786,12 +786,12 @@
},
{
"command": "code-for-ibmi.debug.setup.local",
- "title": "Setup local certificate",
+ "title": "Import local certificate",
"category": "IBM i Debug"
},
{
"command": "code-for-ibmi.debug.start",
- "title": "Start debug server",
+ "title": "Start debug service",
"category": "IBM i Debug"
},
{
diff --git a/src/api/Configuration.ts b/src/api/Configuration.ts
index 347151be1..6ab14494f 100644
--- a/src/api/Configuration.ts
+++ b/src/api/Configuration.ts
@@ -38,7 +38,7 @@ export namespace ConnectionConfiguration {
autoSaveBeforeAction: boolean;
showDescInLibList: boolean;
debugPort: string;
- debugSecure: boolean;
+ debugIsSecure: boolean;
debugUpdateProductionFiles: boolean;
debugEnableDebugTracing: boolean;
[name: string]: any;
@@ -105,7 +105,7 @@ export namespace ConnectionConfiguration {
autoSaveBeforeAction : (parameters.autoSaveBeforeAction === true),
showDescInLibList : (parameters.showDescInLibList === true),
debugPort: (parameters.debugPort || "8005"),
- debugSecure: (parameters.debugSecure === true || parameters.debugSecure === undefined),
+ debugIsSecure: (parameters.debugIsSecure === true),
debugUpdateProductionFiles: (parameters.debugUpdateProductionFiles === true),
debugEnableDebugTracing: (parameters.debugEnableDebugTracing === true),
}
diff --git a/src/api/debug/certificates.ts b/src/api/debug/certificates.ts
index 819d06129..6df21b0a7 100644
--- a/src/api/debug/certificates.ts
+++ b/src/api/debug/certificates.ts
@@ -11,7 +11,7 @@ export function getKeystorePath() {
return path.posix.join(directory, pfxName);
}
-export function getLocalCert(connection: IBMi) {
+export function getLocalCertPath(connection: IBMi) {
const host = connection.currentHost;
return path.join(os.homedir(), `${host}_${crtName}`);
}
@@ -59,17 +59,10 @@ export async function setup(connection: IBMi) {
export async function checkLocalExists(connection: IBMi) {
try {
- await fs.stat(getLocalCert(connection));
+ await fs.stat(getLocalCertPath(connection));
// TODO: if local exists, but it's out of date with the server? e.g. md5 is different for example
return true;
} catch (e) {
return false;
}
-}
-
-export function downloadToLocal(connection: IBMi) {
- return connection.downloadFile(
- getLocalCert(connection),
- path.posix.join(directory, crtName)
- );
}
\ No newline at end of file
diff --git a/src/api/debug/index.ts b/src/api/debug/index.ts
index 91831e9c9..374ee0064 100644
--- a/src/api/debug/index.ts
+++ b/src/api/debug/index.ts
@@ -6,6 +6,7 @@ import path from "path";
import * as certificates from "./certificates";
import * as server from "./server";
+import { copyFileSync } from "fs";
const debugExtensionId = `IBM.ibmidebug`;
@@ -158,26 +159,30 @@ export async function initialise(instance: Instance, context: ExtensionContext)
vscode.window.showInformationMessage(`Certificates already exist on the server.`);
remoteCertsOk = true;
} else {
- const doSetup = await vscode.window.showInformationMessage(`Debug setup`, {
- modal: true,
- detail: `Debug certificates are not setup on the system. Continue with setup?`
- }, `Continue`);
-
- if (doSetup) {
- try {
- await certificates.setup(connection);
- vscode.window.showInformationMessage(`Certificates successfully generated on server.`);
- remoteCertsOk = true;
- remoteCertsAreNew = true;
- } catch (e: any) {
- vscode.window.showErrorMessage(e.message || e);
- }
+
+ }
+
+ const doSetup = await vscode.window.showInformationMessage(`Debug setup`, {
+ modal: true,
+ detail: `${remoteExists
+ ? `Debug certificates already exist on this system! Running this setup will overwrite them, which will require the debug service to be restarted.`
+ : `Debug certificates are not setup on the system.`
+ } Continue with setup?`
+ }, `Continue`);
+
+ if (doSetup) {
+ try {
+ await certificates.setup(connection);
+ vscode.window.showInformationMessage(`Certificates successfully generated on server.`);
+ remoteCertsOk = true;
+ remoteCertsAreNew = true;
+ } catch (e: any) {
+ vscode.window.showErrorMessage(e.message || e);
}
}
if (remoteCertsOk) {
vscode.commands.executeCommand(`setContext`, remoteCertContext, true);
- vscode.commands.executeCommand(`code-for-ibmi.debug.setup.local`, remoteCertsAreNew);
}
} else {
vscode.window.showErrorMessage(`Debug PTF not installed.`);
@@ -188,29 +193,49 @@ export async function initialise(instance: Instance, context: ExtensionContext)
}
}),
- vscode.commands.registerCommand(`code-for-ibmi.debug.setup.local`, async (force: boolean = false) => {
+ vscode.commands.registerCommand(`code-for-ibmi.debug.setup.local`, async () => {
const connection = instance.connection;
if (connection) {
const ptfInstalled = await debugPTFInstalled();
if (ptfInstalled) {
- const localExists = await certificates.checkLocalExists(connection);
let localCertsOk = false;
-
- if (localExists && !force) {
- localCertsOk = true;
- vscode.window.showInformationMessage(`Debug certificates already exist locally. Skipping this step.`);
- } else {
- try {
- await certificates.downloadToLocal(connection);
- vscode.window.showInformationMessage(`Debug certificates successfully downloaded to local device.`);
- localCertsOk = true;
- } catch (e: any) {
- vscode.window.showErrorMessage(`Failed to download new local debug certificate.`);
+ if (connection.config!.debugIsSecure) {
+ const selection = await vscode.window.showInformationMessage(
+ `Client certificate`,
+ {
+ modal: true,
+ detail: `To debug securely, a client certificate needs to be imported.`
+ },
+ `Import certificate`
+ );
+
+ if (selection === `Import certificate`) {
+ const selectedFile = await vscode.window.showOpenDialog({
+ canSelectFiles: true,
+ canSelectFolders: false,
+ canSelectMany: false,
+ title: `Select client certificate`
+ });
+
+ if (selectedFile && selectedFile.length === 1) {
+ try {
+ copyFileSync(selectedFile[0].fsPath, certificates.getLocalCertPath(connection));
+ localCertsOk = true;
+ vscode.window.showInformationMessage(`Certificate imported.`);
+ } catch (e) {
+ vscode.window.showErrorMessage(`Failed to import local certificate.`);
+ }
+ }
}
+ } else {
+ vscode.window.showWarningMessage(`Certificates can only be imported when secure mode is enabled.`, `Open configuration`).then(result => {
+ if (result === `Open configuration`) {
+ vscode.commands.executeCommand(`code-for-ibmi.showAdditionalSettings`);
+ }
+ });
}
-
if (localCertsOk) {
vscode.commands.executeCommand(`setContext`, localCertContext, true);
}
@@ -228,44 +253,35 @@ export async function initialise(instance: Instance, context: ExtensionContext)
const remoteExists = await certificates.checkRemoteExists(connection);
if (remoteExists) {
- const localExists = await certificates.checkLocalExists(connection);
- if (localExists) {
- vscode.window.withProgress({ location: vscode.ProgressLocation.Notification }, async (progress) => {
+ vscode.window.withProgress({ location: vscode.ProgressLocation.Notification }, async (progress) => {
- let startupService = false;
+ let startupService = false;
- progress.report({ increment: 20, message: `Checking if service is already running.` });
- const isRunning = await server.isRunning(connection.config?.debugPort || "8005", instance.content!);
+ progress.report({ increment: 20, message: `Checking if service is already running.` });
+ const isRunning = await server.isRunning(connection.config?.debugPort || "8005", instance.content!);
- if (isRunning) {
- const confirmEndServer = await vscode.window.showInformationMessage(`Starting debug service`, {
- detail: `Looks like the debug service is currently running. Do you want to end it to start a new instance?`,
- modal: true
- }, `End service`);
+ if (isRunning) {
+ const confirmEndServer = await vscode.window.showInformationMessage(`Starting debug service`, {
+ detail: `Looks like the debug service is currently running. Do you want to end it to start a new instance?`,
+ modal: true
+ }, `End service`);
- if (confirmEndServer === `End service`) {
- progress.report({ increment: 25, message: `Ending currently running service.` });
- const endResult = await server.end(connection);
- startupService = true;
- }
- } else {
+ if (confirmEndServer === `End service`) {
+ progress.report({ increment: 25, message: `Ending currently running service.` });
+ const endResult = await server.end(connection);
startupService = true;
}
+ } else {
+ startupService = true;
+ }
- if (startupService) {
- progress.report({ increment: 25, message: `Starting service up.` });
- await server.startup(connection);
- } else {
- vscode.window.showInformationMessage(`Cancelled startup of debug service.`);
- }
- })
-
- } else {
- const localResult = await vscode.window.showErrorMessage(`Local debug certificate does not exist.`, `Setup`);
- if (localResult === `Setup`) {
- vscode.commands.executeCommand(`code-for-ibmi.debug.setup.local`);
+ if (startupService) {
+ progress.report({ increment: 25, message: `Starting service up.` });
+ await server.startup(connection);
+ } else {
+ vscode.window.showInformationMessage(`Cancelled startup of debug service.`);
}
- }
+ })
} else {
vscode.commands.executeCommand(`code-for-ibmi.debug.setup.remote`);
@@ -288,12 +304,14 @@ export async function initialise(instance: Instance, context: ExtensionContext)
if (remoteCerts) {
vscode.commands.executeCommand(`setContext`, remoteCertContext, true);
- const localExists = await certificates.checkLocalExists(instance.connection);
+ if (instance.connection.config!.debugIsSecure) {
+ const localExists = await certificates.checkLocalExists(instance.connection);
- if (localExists) {
- vscode.commands.executeCommand(`setContext`, localCertContext, true);
- } else {
- vscode.commands.executeCommand(`code-for-ibmi.debug.setup.local`);
+ if (localExists) {
+ vscode.commands.executeCommand(`setContext`, localCertContext, true);
+ } else {
+ vscode.commands.executeCommand(`code-for-ibmi.debug.setup.local`);
+ }
}
} else {
const openTut = await vscode.window.showInformationMessage(`Looks like you have the debug PTF installed. Do you want to see the Walkthrough to set it up?`, `Take me there`);
@@ -319,12 +337,12 @@ export async function startDebug(instance: Instance, options: DebugOptions) {
const port = config?.debugPort;
const updateProductionFiles = config?.debugUpdateProductionFiles;
- const enableDebugTracing = config?.debugEnableDebugTracing; // TODO: configurable
+ const enableDebugTracing = config?.debugEnableDebugTracing;
- const secure = config?.debugSecure; // TODO: make configurable
+ const secure = config?.debugIsSecure;
if (secure) {
- process.env[`DEBUG_CA_PATH`] = certificates.getLocalCert(connection!);
+ process.env[`DEBUG_CA_PATH`] = certificates.getLocalCertPath(connection!);
}
const pathKey = options.library.trim() + `/` + options.object.trim();
diff --git a/src/webviews/settings/index.js b/src/webviews/settings/index.js
index b186aebe3..3ca3f47a1 100644
--- a/src/webviews/settings/index.js
+++ b/src/webviews/settings/index.js
@@ -208,11 +208,6 @@ module.exports = class SettingsUI {
field.description = `Default secure port is 8005
. Tells the client which port the debug service is running on.`;
ui.addField(field);
- field = new Field(`checkbox`, `debugSecure`, `Debug securely`);
- field.default = (config.debugSecure ? `checked` : ``);
- field.description = `Ensures that the client and debug service are connected securely.`;
- ui.addField(field);
-
field = new Field(`checkbox`, `debugUpdateProductionFiles`, `Update production files`);
field.default = (config.debugUpdateProductionFiles ? `checked` : ``);
field.description = `Determines whether the job being debugged can update objects in production (*PROD
) libraries.`;
@@ -222,6 +217,11 @@ module.exports = class SettingsUI {
field.default = (config.debugEnableDebugTracing ? `checked` : ``);
field.description = `Tells the debug service to send more data to the client. Only useful for debugging issues in the service. Not recommended for general debugging.`;
ui.addField(field);
+
+ field = new Field(`checkbox`, `debugIsSecure`, `Debug securely`);
+ field.default = (config.debugIsSecure ? `checked` : ``);
+ field.description = `Tells the debug service to authenticate by server and client certificates. Ensure that the client certificate is imported when enabled.`;
+ ui.addField(field);
}
ui.addField(new Field(`hr`));