Skip to content
Open
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
19 changes: 19 additions & 0 deletions src/lib/VncScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface Props {
onConnect?: (rfb?: RFB) => void;
onDisconnect?: (rfb?: RFB) => void;
onCredentialsRequired?: (rfb?: RFB) => void;
onServerVerification?: (e: { detail: { type: string, publickey: Uint8Array } }, rfb: RFB | undefined) => void;
onSecurityFailure?: (e?: { detail: { status: number, reason: string } }) => void;
onClipboard?: (e?: { detail: { text: string } }) => void;
onBell?: () => void;
Expand All @@ -51,6 +52,7 @@ export enum Events {
connect,
disconnect,
credentialsrequired,
serververification,
securityfailure,
clipboard,
bell,
Expand Down Expand Up @@ -112,6 +114,7 @@ const VncScreen: React.ForwardRefRenderFunction<VncScreenHandle, Props> = (props
onBell,
onDesktopName,
onCapabilities,
onServerVerification,
} = props;

const logger = {
Expand Down Expand Up @@ -187,6 +190,21 @@ const VncScreen: React.ForwardRefRenderFunction<VncScreenHandle, Props> = (props
logger.info(`Desktop name is ${e.detail.name}`);
};

const _onServerVerification = async (e: { detail: { type: string, publickey: Uint8Array } }) => {
const rfb = getRfb();
if (onServerVerification) {
onServerVerification(e, rfb ?? undefined);
return;
}

if (e.detail.type === 'RSA') {
const fingerprint = await window.crypto.subtle.digest("SHA-1", e.detail.publickey)
Copy link
Owner

Choose a reason for hiding this comment

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

Currently the fingerprint is only logged, it would be better if we could expose the fingerprint (if present) by forwarding the ref to the parent component, so that the fingerprint can be programmatically verified if needed.

The easiest way to do it in my opinion is to assign it to the RFB object (if it has a rfb.fingerprint field?) or just on the VNCScreenHandle object.

P.S. I'm not sure the fingerprint needs to be used by a client in any scenario, but I assume that's the purpose of it - to make sure the fingerprint is in accordance with the VNC server

Copy link
Owner

Choose a reason for hiding this comment

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

I added support for react 19, which has caused some conflicts in the PR. Sorry for the inconvenience, it would be great if you could resolve the merge conflicts.

logger.info(`Fingerprint is ${Array.from(new Uint8Array(fingerprint).slice(0, 8)).map(
x => x.toString(16).padStart(2, '0')).join('-')}`);
rfb?.approveServer();
}
};

const disconnect = () => {
const rfb = getRfb();
try {
Expand Down Expand Up @@ -250,6 +268,7 @@ const VncScreen: React.ForwardRefRenderFunction<VncScreenHandle, Props> = (props
eventListeners.current.bell = onBell;
eventListeners.current.desktopname = _onDesktopName;
eventListeners.current.capabilities = onCapabilities;
eventListeners.current.serververification = _onServerVerification;

(Object.keys(eventListeners.current) as (keyof typeof Events)[]).forEach((event) => {
if (eventListeners.current[event]) {
Expand Down