starsys-tech / projector-server

Server-side library for running Swing applications remotely
https://youtrack.jetbrains.com/issues/PRJ
Other
0 stars 0 forks source link

剪贴板加解密支持 Clipboard encryption and decryption support #1

Open gudaoxuri opened 2 years ago

gudaoxuri commented 2 years ago

关联问题: https://youtrack.jetbrains.com/issue/PRJ-815

gudaoxuri commented 2 years ago

解决路径:

一是尝试在projector-client工程下修改,但对服务器事件的捕捉有问题

二是发现所有的操作都会汇聚到 CopyHandlerPasteHandler 这样就有两种选项:

  1. 写一个intellij插件,实现CopyPastePreProcessor方法处理加解密,该选项的问题在于插件如果被禁用怎么办?
  2. 修改 CopyHandlerPasteHandler 处理加解密,该选项侵入性很强 但无论如何方案二都一个共同的问题:即只对编辑器事件有效,terminal下就无法处理了,这个漏洞很严重

三是修改 org/jetbrains/projector/awt/PClipboard.kt ,其中的 putContentsWithoutLastContentsUpdateCtrl + V 事件中会被调用, setContents 会有所有剪切、复制事件中会被调用。唯一的遗憾是右键菜单中的粘贴无法调起,但这是可以容忍的。

因此目前基于方案三实现。这也有两个选项:

  1. 创建新的 Transferable 写到剪贴板中,尝试在 projector-awt 中引入新的依赖:
  implementation("com.jetbrains.intellij.platform:ide-impl:$intellijPlatformVersion"){
    exclude(group = "com.jetbrains.intellij.platform",module="analysis-impl")
    exclude(group = "com.jetbrains.intellij.platform",module="editor-ex")
    exclude(group = "com.jetbrains.intellij.platform",module="remote-core")
    exclude(group = "com.jetbrains.intellij.platform",module="ide-core-impl")
    exclude(group = "com.jetbrains.intellij.platform",module="util-ui")
    exclude(group = "com.jetbrains.intellij.platform",module="vfs-impl")
    exclude(group = "com.jetbrains.intellij.platform",module="analysis")
    exclude(group = "com.jetbrains.intellij.platform",module="core-ui")
    exclude(group = "com.jetbrains.intellij.platform",module="core")
    exclude(group = "com.jetbrains.intellij.platform",module="ide-core")
    exclude(group = "com.jetbrains.intellij.platform",module="project-model")
    exclude(group = "com.jetbrains.intellij.platform",module="resources-en")
    exclude(group = "com.jetbrains.intellij.platform",module="util")
    exclude(group = "com.jetbrains.intellij.java",module="java-gui-forms-rt")
    exclude(group = "ai.grazie.utils")
    exclude(group = "ai.grazie.nlp")
    exclude(group = "ai.grazie.spell")
    exclude(group = "com.jetbrains.infra")
  }

org/jetbrains/projector/awt/PClipboard.ktsetContents 修改成类似如下形式:

if(contents is TextBlockTransferable){
  val myTextField = contents.javaClass.getDeclaredField("myText");
  myTextField.trySetAccessible();
  val myText = myTextField.get(contents) as String;
  val myRawTextField = contents.javaClass.getDeclaredField("myRawText");
  myRawTextField.trySetAccessible();
  val myRawText = myTextField.get(contents) as RawText;
  val myExtraDataField = contents.javaClass.getDeclaredField("myExtraData");
  myExtraDataField.trySetAccessible();
  val myExtraData = myExtraDataField.get(contents) as Collection<? extends TextBlockTransferableData >;
  contents = TextBlockTransferable(
   myText,
   myExtraData,
   myRawText
  )
}

但不幸的 contents的实现是 TextBlockTransferable,但该实现不是 com.jetbrains.intellij.platform:ide-impl 而是 platform-impl.jar ,后者看起来更不控。

image

因此,当前的做法是直接用反射修改内部对象而不是创建一新的对象,坏处是侵入性很强,但带来的好处是(暂时)没有新的依赖,只需要修改 PClipboard.kt 的代码,可读性及可维护性也更高。