Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikkel Krautz <mikkel@krautz.dk>2016-06-06 23:01:02 +0300
committerMikkel Krautz <mikkel@krautz.dk>2016-06-06 23:01:02 +0300
commit6091625bc9ff22ea96065168b30f8ae9f5507b69 (patch)
tree420a2d09a83f85d2cf329a9414e436465318162f /src/murmur/MurmurIce.cpp
parent18e801431b376f85fbf80f0b505680a11c6dd783 (diff)
Murmur.ice: add updateCertificate() method.
This allows live certificate/private key reloading for individual virtual servers. This makes it possible to integrate Murmur with an external Let's Encrypt script, without having to fully restart the virtual server in the process.
Diffstat (limited to 'src/murmur/MurmurIce.cpp')
-rw-r--r--src/murmur/MurmurIce.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/murmur/MurmurIce.cpp b/src/murmur/MurmurIce.cpp
index ad658c208..8be048ddd 100644
--- a/src/murmur/MurmurIce.cpp
+++ b/src/murmur/MurmurIce.cpp
@@ -1534,6 +1534,72 @@ static void impl_Server_getUptime(const ::Murmur::AMD_Server_getUptimePtr cb, in
cb->ice_response(static_cast<int>(server->tUptime.elapsed()/1000000LL));
}
+static void impl_Server_updateCertificate(const ::Murmur::AMD_Server_updateCertificatePtr cb, int server_id, const ::std::string& certificate, const ::std::string& privateKey, const ::std::string& passphrase) {
+ NEED_SERVER;
+
+ QByteArray certPem(certificate.c_str());
+ QByteArray privateKeyPem(privateKey.c_str());
+ QByteArray passphraseBytes(passphrase.c_str());
+
+ // Verify that we can load the certificate.
+ QSslCertificate cert(certPem);
+ if (cert.isNull()) {
+ ERR_clear_error();
+ cb->ice_exception(InvalidInputDataException());
+ return;
+ }
+
+ // Verify that we can load the private key.
+ QSslKey privKey(privateKeyPem, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, passphraseBytes);
+ if (privKey.isNull()) {
+ ERR_clear_error();
+ cb->ice_exception(InvalidInputDataException());
+ return;
+ }
+
+ // Ensure that the private key is usable with the given
+ // certificate.
+ //
+ // Right now, we only support RSA keys in Murmur.
+ //
+ // To determine if the private key matches the certificate,
+ // we acquire the public key from the certificate and check
+ // that the modulus (n) and the public exponent (e) match
+ // those of the private key.
+ QSslKey pubKey = cert.publicKey();
+
+ if (privKey.algorithm() != QSsl::Rsa || pubKey.algorithm() != QSsl::Rsa) {
+ ERR_clear_error();
+ cb->ice_exception(InvalidInputDataException());
+ return;
+ }
+
+ RSA *privRSA = reinterpret_cast<RSA *>(privKey.handle());
+ RSA *pubRSA = reinterpret_cast<RSA *>(pubKey.handle());
+
+ if (BN_cmp(pubRSA->n, privRSA->n) != 0) {
+ ERR_clear_error();
+ cb->ice_exception(InvalidInputDataException());
+ return;
+ }
+
+ if (BN_cmp(pubRSA->e, privRSA->e) != 0) {
+ ERR_clear_error();
+ cb->ice_exception(InvalidInputDataException());
+ return;
+ }
+
+ // All our sanity checks passed.
+ // The certificate and private key are usable, so
+ // update the server to use them.
+ server->setConf("certificate", u8(certificate));
+ server->setConf("key", u8(privateKey));
+ server->setConf("passphrase", u8(passphrase));
+ server->initializeCert();
+
+ cb->ice_response();
+}
+
static void impl_Server_addUserToGroup(const ::Murmur::AMD_Server_addUserToGroupPtr cb, int server_id, ::Ice::Int channelid, ::Ice::Int session, const ::std::string& group) {
NEED_SERVER;
NEED_PLAYER;