Skip to main content

源码阅读[kde/krfb]: noWallet

noWallet 为true 时,krfb 启动时将默认不使用Kwallet

noWallet 的值以 KrfbConfig::noWallet()的形式在代码中传递,精简后的代码片段

void MainWindow::showConfiguration()
{
    s_prevNoWallet = KrfbConfig::noWallet();
    connect(dialog, &KConfigDialog::settingsChanged, this, [this] () {
        // check if kwallet config has changed
        if (s_prevNoWallet != KrfbConfig::noWallet()) {
            // try to apply settings immediately
            if (KrfbConfig::noWallet()) {
                InvitationsRfbServer::instance->closeKWallet();
            } else {
                InvitationsRfbServer::instance->openKWallet();
                // erase stored passwords from krfbconfig file
                KConfigGroup securityConfigGroup(KSharedConfig::openConfig(), "Security");
                securityConfigGroup.deleteEntry("desktopPassword");
                securityConfigGroup.deleteEntry("unattendedPassword");
            }
        }
    });
}

rfbserver init、析构函数、saveSecuritySettings

//static
void InvitationsRfbServer::init()
{
    if (KrfbConfig::noWallet()) {
        instance->walletOpened(false);
    } else {
        instance->openKWallet();
    }
}

InvitationsRfbServer::~InvitationsRfbServer()
{
    InvitationsRfbServer::stop();  // calling virtual funcs in destructor is bad
    saveSecuritySettings();
    // ^^ also saves passwords in kwallet,
    //    do it before closing kwallet
    if (!KrfbConfig::noWallet() && m_wallet) {
        closeKWallet();
    }
}


// one place to deal with all security configuration
void InvitationsRfbServer::saveSecuritySettings()
{
    if (KrfbConfig::noWallet()) {
        // save passwords in config file only if not using kwallet integration
        secConfigGroup.writeEntry("desktopPassword", KStringHandler::obscure(m_desktopPassword));
        secConfigGroup.writeEntry("unattendedPassword", KStringHandler::obscure(m_unattendedPassword));
    } else {
        // using KWallet, erase possibly stored passwords from krfbrc file
		...
    }
    KrfbConfig::self()->save();
}

KrfbConfig的类看起来是 krfbconfig.h 头文件引入的,但是源码中没有,通过V=s -j1 编译看到,是 kconfig_compiler_kf5 (kconfig提供) 通过 krfb/krfb.kcfg krfb/krfbconfig.kcfgc 生成

[ 44%] Generating krfbconfig.h, krfbconfig.cpp
cd /build/krfb-20.12.0102.3/obj-aarch64-linux-gnu/krfb && /usr/lib/libexec/kf5/kconfig_compiler_kf5 /build/krfb-20.12.0102.3/krfb/krfb.kcfg /build/krfb-20.12.0102.3/krfb/krfbconfig.kcfgc -d /build/krfb-20.12.0102.3/obj-aarch64-linux-gnu/krfb/

cat krfb/krfbconfig.kcfgc

File=krfb.kcfg
ClassName=KrfbConfig
Singleton=true

krfb/krfb.kcfg

<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
                          http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
  <kcfgfile name="krfbrc"/>
  <group name="Security">
   <entry name="noWallet" type="Bool">
      <label>Do not store passwords in KWallet</label>
      <default>false</default>
    </entry>
  </group>
</kcfg>

另外,kcfg_noWallet, 即 Security设置中的Do not store passwords using KDE wallet, 是在UI文件 krfb/ui/configsecurity.ui 设置

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Security</class>
 <widget class="QWidget" name="Security">
  <layout class="QVBoxLayout">
   <item>
    <widget class="QCheckBox" name="kcfg_noWallet">
     <property name="text">
      <string>Do not store passwords using KDE wallet</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
</ui>

点击checkbox 时, 根据 checked 来显示或者隐藏橘黄色的警示横幅:

        // show warning when "noWallet" checkbox is checked
        QObject::connect(kcfg_noWallet, &QCheckBox::toggled, this, [this] (bool checked) {
            walletWarning->setVisible(checked);
        });

可以通过Qt Creator Designer 打开UI 文件修改是否默认勾选,但是测试krfb/krfb.kcfg 修改后这里会自动勾选,所以暂无修改需求

diff --git a/krfb/ui/configsecurity.ui b/krfb/ui/configsecurity.ui
index 531591b..e65cc8e 100644
--- a/krfb/ui/configsecurity.ui
+++ b/krfb/ui/configsecurity.ui
@@ -26,6 +26,9 @@
      <property name="text">
       <string>Do not store passwords using KDE wallet</string>
      </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
     </widget>
    </item>
    <item>