]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/commitdiff
unrealircd::rpc_password is now encrypted with secret::key (XChaCha20-Poly1305-IETF)
authorBram Matthys <redacted>
Sat, 22 Apr 2023 15:04:50 +0000 (17:04 +0200)
committerBram Matthys <redacted>
Sat, 22 Apr 2023 15:08:40 +0000 (17:08 +0200)
Again, the purpose is so if any bad person gets a copy of your DB then the
stored RPC password is still useless since they also need your config/config.php.

Old unencrypted unrealircd::rpc_password entries are automatically
encrypted (upgraded).

Similar to previous commit 6b08fcb99e66665e7e4f345702915d7192fcd27b
this means you cannot blindly 'rm config/config.php' and then expect
your existing DB to still work with a random new (and different) key.

common.php
connection.php

index 7771f5e9afbe72b04de77cfbdbbede93aba6cca4..a7fb94e0e2e253c42bb485ef708358a388228ffb 100644 (file)
@@ -191,6 +191,33 @@ function generate_secrets()
                $config['secrets']['key'] = rtrim(base64_encode(sodium_crypto_aead_xchacha20poly1305_ietf_keygen()),'=');
 }
 
+function secret_encrypt(string $text)
+{
+       GLOBAL $config;
+
+       $key = base64_decode($config['secrets']['key']);
+       $nonce = \random_bytes(\SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
+       $encrypted_text = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($text, '', $nonce, $key);
+       return "secret:".rtrim(base64_encode($nonce),'=').':'.rtrim(base64_encode($encrypted_text),'='); // secret:base64(NONCE):base64(ENCRYPTEDTEXT)
+}
+
+function secret_decrypt(string $crypted)
+{
+       GLOBAL $config;
+
+       $key = base64_decode($config['secrets']['key']);
+       $d = explode(":", $crypted);
+       if (count($d) != 3)
+               return null;
+       $nonce = base64_decode($d[1]);
+       $ciphertext = base64_decode($d[2]);
+
+       $ret = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($ciphertext, '', $nonce, $key);
+       if ($ret === false)
+               return null;
+       return $ret;
+}
+
 function upgrade_check()
 {
        GLOBAL $config_transition_unreal_server;
@@ -201,11 +228,24 @@ function upgrade_check()
                write_config();
 
        /* Our own stuff may need upgrading.. */
+       /* - generating secrets */
        if (!isset($config['secrets']))
        {
                generate_secrets();
                write_config_file();
        }
+       /* - encrypting rpc_password */
+       if (isset($config['unrealircd']) &&
+           isset($config['unrealircd']['rpc_password']) &&
+           !str_starts_with($config['unrealircd']['rpc_password'], "secret:"))
+       {
+               $ret = secret_encrypt($config['unrealircd']['rpc_password']);
+               if ($ret !== false)
+               {
+                       $config['unrealircd']['rpc_password'] = $ret;
+                       write_config('unrealircd');
+               }
+       }
 
        $version = get_version();
        if (!isset($config['webpanel_version']))
index 114088fa7dace6abd9ef579b48f4737dfc199a8f..287f2b314f75b5c241baf2e61d426435b8c4d883 100644 (file)
@@ -11,6 +11,8 @@ function connect_to_ircd()
        $port = get_config("unrealircd::port");
        $rpc_user = get_config("unrealircd::rpc_user");
        $rpc_password = get_config("unrealircd::rpc_password");
+       if (str_starts_with($rpc_password, "secret:"))
+               $rpc_password = secret_decrypt($rpc_password);
 
        if (!$host || !$port || !$rpc_user || !$rpc_password)
                die("Unable to find RPC credentials in your config.php");