mirror of
https://github.com/bitwarden/browser
synced 2025-12-20 18:23:31 +00:00
[PM-7846] Implement a rust based native messaging proxy and IPC system (#9894)
* [PM-7846] Implement a rust based native messaging proxy and IPC system
* Only build desktop_proxy
* Bundle the desktop_proxy file
* Make sys deps optional for the proxy
* Restore accidentally deleted after-sign
* Update native cache to contain dist folder
* Add some test logging
* Native module cache seems very aggressive
* Fix invalid directory
* Fix debug print
* Remove cache force
* Remove cache debug code
* Only log to file in debug builds
* Place the binary in the correct place for mac and make sure it's signed
* Fix platform paths
* Test unsigned appx
* Revert "Test unsigned appx"
This reverts commit e47535440a.
* Fix comment
* Remove logs
* Use debug builds in native code, and test private path on MacOS
* Add connected message
* Update IPC API comments
* Update linux to also use XDG_ dir
* Update main.rs comment
* Improve docs and split some tasks spawned into separate functions
* Update send docs and return number of elements sent
* Mark `listen` as async to ensure it runs in a tokio context, handle errors better
* Add log on client channel closed
* Move binary to MacOS folder, and sign it manually so it gets the correct entitlements
* Fix some review comments
* Run prettier
* Added missing zbus_polkit dep
* Extract magic number and increase it to match spec
* Comment fix
* Use Napi object, combine nativeBinding export, always log to file
* Missed one comment
* Remove unnecessary generics
* Correct comment
* Select only codesigning identities
* Filter certificates
* Also add local dev cert
* Remove log
* Fix package ID
* debug_assert won't run the pop() in release mode
* Better error messages
* Fix review comments
* Remove unnecessary comment
* Update napi generated TS file
* Temporary fix for DDG
This commit is contained in:
@@ -1,34 +1,34 @@
|
||||
import { existsSync, promises as fs } from "fs";
|
||||
import { Socket } from "net";
|
||||
import { homedir, userInfo } from "os";
|
||||
import * as path from "path";
|
||||
import * as util from "util";
|
||||
|
||||
import { ipcMain } from "electron";
|
||||
import * as ipc from "node-ipc";
|
||||
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { ipc } from "@bitwarden/desktop-napi";
|
||||
|
||||
import { getIpcSocketRoot } from "../proxy/ipc";
|
||||
import { isDev } from "../utils";
|
||||
|
||||
import { WindowMain } from "./window.main";
|
||||
|
||||
export class NativeMessagingMain {
|
||||
private connected: Socket[] = [];
|
||||
private socket: any;
|
||||
private ipcServer: ipc.IpcServer | null;
|
||||
private connected: number[] = [];
|
||||
|
||||
constructor(
|
||||
private logService: LogService,
|
||||
private windowMain: WindowMain,
|
||||
private userPath: string,
|
||||
private exePath: string,
|
||||
private appPath: string,
|
||||
) {
|
||||
ipcMain.handle(
|
||||
"nativeMessaging.manifests",
|
||||
async (_event: any, options: { create: boolean }) => {
|
||||
if (options.create) {
|
||||
this.listen();
|
||||
try {
|
||||
await this.listen();
|
||||
await this.generateManifests();
|
||||
} catch (e) {
|
||||
this.logService.error("Error generating manifests: " + e);
|
||||
@@ -51,8 +51,8 @@ export class NativeMessagingMain {
|
||||
"nativeMessaging.ddgManifests",
|
||||
async (_event: any, options: { create: boolean }) => {
|
||||
if (options.create) {
|
||||
this.listen();
|
||||
try {
|
||||
await this.listen();
|
||||
await this.generateDdgManifests();
|
||||
} catch (e) {
|
||||
this.logService.error("Error generating duckduckgo manifests: " + e);
|
||||
@@ -72,56 +72,46 @@ export class NativeMessagingMain {
|
||||
);
|
||||
}
|
||||
|
||||
listen() {
|
||||
ipc.config.id = "bitwarden";
|
||||
ipc.config.retry = 1500;
|
||||
const ipcSocketRoot = getIpcSocketRoot();
|
||||
if (ipcSocketRoot != null) {
|
||||
ipc.config.socketRoot = ipcSocketRoot;
|
||||
async listen() {
|
||||
if (this.ipcServer) {
|
||||
this.ipcServer.stop();
|
||||
}
|
||||
|
||||
ipc.serve(() => {
|
||||
ipc.server.on("message", (data: any, socket: any) => {
|
||||
this.socket = socket;
|
||||
this.windowMain.win.webContents.send("nativeMessaging", data);
|
||||
});
|
||||
|
||||
ipcMain.on("nativeMessagingReply", (event, msg) => {
|
||||
if (this.socket != null && msg != null) {
|
||||
this.send(msg, this.socket);
|
||||
this.ipcServer = await ipc.IpcServer.listen("bitwarden", (error, msg) => {
|
||||
switch (msg.kind) {
|
||||
case ipc.IpcMessageType.Connected: {
|
||||
this.connected.push(msg.clientId);
|
||||
this.logService.info("Native messaging client " + msg.clientId + " has connected");
|
||||
break;
|
||||
}
|
||||
});
|
||||
case ipc.IpcMessageType.Disconnected: {
|
||||
const index = this.connected.indexOf(msg.clientId);
|
||||
if (index > -1) {
|
||||
this.connected.splice(index, 1);
|
||||
}
|
||||
|
||||
ipc.server.on("connect", (socket: Socket) => {
|
||||
this.connected.push(socket);
|
||||
});
|
||||
|
||||
ipc.server.on("socket.disconnected", (socket, destroyedSocketID) => {
|
||||
const index = this.connected.indexOf(socket);
|
||||
if (index > -1) {
|
||||
this.connected.splice(index, 1);
|
||||
this.logService.info("Native messaging client " + msg.clientId + " has disconnected");
|
||||
break;
|
||||
}
|
||||
|
||||
this.socket = null;
|
||||
ipc.log("client " + destroyedSocketID + " has disconnected!");
|
||||
});
|
||||
case ipc.IpcMessageType.Message:
|
||||
this.windowMain.win.webContents.send("nativeMessaging", JSON.parse(msg.message));
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
ipc.server.start();
|
||||
}
|
||||
|
||||
stop() {
|
||||
ipc.server.stop();
|
||||
// Kill all existing connections
|
||||
this.connected.forEach((socket) => {
|
||||
if (!socket.destroyed) {
|
||||
socket.destroy();
|
||||
ipcMain.on("nativeMessagingReply", (event, msg) => {
|
||||
if (msg != null) {
|
||||
this.send(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
send(message: object, socket: any) {
|
||||
ipc.server.emit(socket, "message", message);
|
||||
stop() {
|
||||
this.ipcServer?.stop();
|
||||
}
|
||||
|
||||
send(message: object) {
|
||||
this.ipcServer?.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
async generateManifests() {
|
||||
@@ -331,11 +321,20 @@ export class NativeMessagingMain {
|
||||
}
|
||||
|
||||
private binaryPath() {
|
||||
if (process.platform === "win32") {
|
||||
return path.join(path.dirname(this.exePath), "resources", "native-messaging.bat");
|
||||
const ext = process.platform === "win32" ? ".exe" : "";
|
||||
|
||||
if (isDev()) {
|
||||
return path.join(
|
||||
this.appPath,
|
||||
"..",
|
||||
"desktop_native",
|
||||
"target",
|
||||
"debug",
|
||||
`desktop_proxy${ext}`,
|
||||
);
|
||||
}
|
||||
|
||||
return this.exePath;
|
||||
return path.join(path.dirname(this.exePath), `desktop_proxy${ext}`);
|
||||
}
|
||||
|
||||
private getRegeditInstance() {
|
||||
|
||||
Reference in New Issue
Block a user