From 36b19b946dfca1ec6e098dc31ceaf1bf23f33977 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 7 Aug 2024 10:35:51 +0200 Subject: [PATCH] Don't abuse auth failure exception This exception is for when the user fails to authenticate, not all possible errors that might occur during the authentication phase. Use more appropriate exception types for the various other problems that might occur, so that we can present things more accurately to the user. --- common/rfb/CSecurityDH.cxx | 8 +-- common/rfb/CSecurityMSLogonII.cxx | 4 +- common/rfb/CSecurityRSAAES.cxx | 24 ++++---- common/rfb/CSecurityTLS.cxx | 97 +++++++++++++++++-------------- common/rfb/CSecurityVeNCrypt.cxx | 12 ++-- common/rfb/SSecurityPlain.cxx | 2 +- common/rfb/SSecurityRSAAES.cxx | 4 +- common/rfb/SSecurityTLS.cxx | 74 +++++++++++++---------- common/rfb/SSecurityVeNCrypt.cxx | 10 ++-- common/rfb/SSecurityVncAuth.cxx | 2 +- 10 files changed, 130 insertions(+), 107 deletions(-) diff --git a/common/rfb/CSecurityDH.cxx b/common/rfb/CSecurityDH.cxx index 6d9650bd..25797792 100644 --- a/common/rfb/CSecurityDH.cxx +++ b/common/rfb/CSecurityDH.cxx @@ -86,9 +86,9 @@ bool CSecurityDH::readKey() uint16_t gen = is->readU16(); keyLength = is->readU16(); if (keyLength < MinKeyLength) - throw AuthFailureException("DH key is too short"); + throw Exception("DH key is too short"); if (keyLength > MaxKeyLength) - throw AuthFailureException("DH key is too long"); + throw Exception("DH key is too long"); if (!is->hasDataOrRestore(keyLength * 2)) return false; is->clearRestorePoint(); @@ -135,10 +135,10 @@ void CSecurityDH::writeCredentials() throw ConnFailedException("failed to generate random padding"); rs.readBytes(buf, 128); if (username.size() >= 64) - throw AuthFailureException("username is too long"); + throw Exception("username is too long"); memcpy(buf, username.c_str(), username.size() + 1); if (password.size() >= 64) - throw AuthFailureException("password is too long"); + throw Exception("password is too long"); memcpy(buf + 64, password.c_str(), password.size() + 1); aes128_encrypt(&aesCtx, 128, buf, buf); diff --git a/common/rfb/CSecurityMSLogonII.cxx b/common/rfb/CSecurityMSLogonII.cxx index e721cdfc..24bd4cbd 100644 --- a/common/rfb/CSecurityMSLogonII.cxx +++ b/common/rfb/CSecurityMSLogonII.cxx @@ -127,10 +127,10 @@ void CSecurityMSLogonII::writeCredentials() rs.readBytes(user, 256); rs.readBytes(pass, 64); if (username.size() >= 256) - throw AuthFailureException("username is too long"); + throw Exception("username is too long"); memcpy(user, username.c_str(), username.size() + 1); if (password.size() >= 64) - throw AuthFailureException("password is too long"); + throw Exception("password is too long"); memcpy(pass, password.c_str(), password.size() + 1); // DES-CBC with the original key as IV, and the reversed one as the DES key diff --git a/common/rfb/CSecurityRSAAES.cxx b/common/rfb/CSecurityRSAAES.cxx index 96d96b01..9b418c64 100644 --- a/common/rfb/CSecurityRSAAES.cxx +++ b/common/rfb/CSecurityRSAAES.cxx @@ -156,7 +156,7 @@ void CSecurityRSAAES::writePublicKey() if (!rsa_generate_keypair(&clientPublicKey, &clientKey, &rs, random_func, nullptr, nullptr, clientKeyLength, 0)) - throw AuthFailureException("failed to generate key"); + throw Exception("failed to generate key"); clientKeyN = new uint8_t[rsaKeySize]; clientKeyE = new uint8_t[rsaKeySize]; nettle_mpz_get_str_256(rsaKeySize, clientKeyN, clientPublicKey.n); @@ -175,9 +175,9 @@ bool CSecurityRSAAES::readPublicKey() is->setRestorePoint(); serverKeyLength = is->readU32(); if (serverKeyLength < MinKeyLength) - throw AuthFailureException("server key is too short"); + throw Exception("server key is too short"); if (serverKeyLength > MaxKeyLength) - throw AuthFailureException("server key is too long"); + throw Exception("server key is too long"); size_t size = (serverKeyLength + 7) / 8; if (!is->hasDataOrRestore(size * 2)) return false; @@ -190,7 +190,7 @@ bool CSecurityRSAAES::readPublicKey() nettle_mpz_set_str_256_u(serverKey.n, size, serverKeyN); nettle_mpz_set_str_256_u(serverKey.e, size, serverKeyE); if (!rsa_public_key_prepare(&serverKey)) - throw AuthFailureException("server key is invalid"); + throw Exception("server key is invalid"); return true; } @@ -216,7 +216,7 @@ void CSecurityRSAAES::verifyServer() "Please verify that the information is correct and press \"Yes\". " "Otherwise press \"No\"", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); if (!msg->showMsgBox(UserMsgBox::M_YESNO, title, text.c_str())) - throw AuthFailureException("server key mismatch"); + throw Exception("server key mismatch"); } void CSecurityRSAAES::writeRandom() @@ -237,7 +237,7 @@ void CSecurityRSAAES::writeRandom() } if (!res) { mpz_clear(x); - throw AuthFailureException("failed to encrypt random"); + throw Exception("failed to encrypt random"); } uint8_t* buffer = new uint8_t[serverKey.size]; nettle_mpz_get_str_256(serverKey.size, buffer, x); @@ -256,7 +256,7 @@ bool CSecurityRSAAES::readRandom() is->setRestorePoint(); size_t size = is->readU16(); if (size != clientKey.size) - throw AuthFailureException("client key length doesn't match"); + throw Exception("client key length doesn't match"); if (!is->hasDataOrRestore(size)) return false; is->clearRestorePoint(); @@ -269,7 +269,7 @@ bool CSecurityRSAAES::readRandom() if (!rsa_decrypt(&clientKey, &randomSize, serverRandom, x) || randomSize != (size_t)keySize / 8) { mpz_clear(x); - throw AuthFailureException("failed to decrypt server random"); + throw Exception("failed to decrypt server random"); } mpz_clear(x); return true; @@ -398,7 +398,7 @@ bool CSecurityRSAAES::readHash() sha256_digest(&ctx, hashSize, realHash); } if (memcmp(hash, realHash, hashSize) != 0) - throw AuthFailureException("hash doesn't match"); + throw Exception("hash doesn't match"); return true; } @@ -428,7 +428,7 @@ bool CSecurityRSAAES::readSubtype() return false; subtype = rais->readU8(); if (subtype != secTypeRA2UserPass && subtype != secTypeRA2Pass) - throw AuthFailureException("unknown RSA-AES subtype"); + throw Exception("unknown RSA-AES subtype"); return true; } @@ -444,7 +444,7 @@ void CSecurityRSAAES::writeCredentials() if (subtype == secTypeRA2UserPass) { if (username.size() > 255) - throw AuthFailureException("username is too long"); + throw Exception("username is too long"); raos->writeU8(username.size()); raos->writeBytes((const uint8_t*)username.data(), username.size()); } else { @@ -452,7 +452,7 @@ void CSecurityRSAAES::writeCredentials() } if (password.size() > 255) - throw AuthFailureException("password is too long"); + throw Exception("password is too long"); raos->writeU8(password.size()); raos->writeBytes((const uint8_t*)password.data(), password.size()); raos->flush(); diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx index f9775215..eca1ea74 100644 --- a/common/rfb/CSecurityTLS.cxx +++ b/common/rfb/CSecurityTLS.cxx @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -88,8 +89,9 @@ CSecurityTLS::CSecurityTLS(CConnection* cc_, bool _anon) anon(_anon), tlsis(nullptr), tlsos(nullptr), rawis(nullptr), rawos(nullptr) { - if (gnutls_global_init() != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_global_init failed"); + int err = gnutls_global_init(); + if (err != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_global_init()", err); } void CSecurityTLS::shutdown() @@ -149,17 +151,21 @@ bool CSecurityTLS::processMsg() client = cc; if (!session) { + int ret; + if (!is->hasData(1)) return false; if (is->readU8() == 0) - throw AuthFailureException("Server failed to initialize TLS session"); + throw Exception("Server failed to initialize TLS session"); - if (gnutls_init(&session, GNUTLS_CLIENT) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_init failed"); + ret = gnutls_init(&session, GNUTLS_CLIENT); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_init()", ret); - if (gnutls_set_default_priority(session) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_set_default_priority failed"); + ret = gnutls_set_default_priority(session); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_set_default_priority()", ret); setParam(); @@ -182,7 +188,7 @@ bool CSecurityTLS::processMsg() vlog.error("TLS Handshake failed: %s\n", gnutls_strerror (err)); shutdown(); - throw AuthFailureException("TLS Handshake failed"); + throw rdr::TLSException("TLS Handshake failed", err); } vlog.debug("TLS handshake completed with %s", @@ -209,7 +215,7 @@ void CSecurityTLS::setParam() prio = (char*)malloc(strlen(Security::GnuTLSPriority) + strlen(kx_anon_priority) + 1); if (prio == nullptr) - throw AuthFailureException("Not enough memory for GnuTLS priority string"); + throw Exception("Not enough memory for GnuTLS priority string"); strcpy(prio, Security::GnuTLSPriority); if (anon) @@ -222,7 +228,7 @@ void CSecurityTLS::setParam() if (ret != GNUTLS_E_SUCCESS) { if (ret == GNUTLS_E_INVALID_REQUEST) vlog.error("GnuTLS priority syntax error at: %s", err); - throw AuthFailureException("gnutls_set_priority_direct failed"); + throw rdr::TLSException("gnutls_set_priority_direct()", ret); } } else if (anon) { const char *err; @@ -234,7 +240,7 @@ void CSecurityTLS::setParam() if (ret != GNUTLS_E_SUCCESS) { if (ret == GNUTLS_E_INVALID_REQUEST) vlog.error("GnuTLS priority syntax error at: %s", err); - throw AuthFailureException("gnutls_set_default_priority_append failed"); + throw rdr::TLSException("gnutls_set_default_priority_append()", ret); } #else // We don't know what the system default priority is, so we guess @@ -245,7 +251,7 @@ void CSecurityTLS::setParam() prio = (char*)malloc(strlen(gnutls_default_priority) + strlen(kx_anon_priority) + 1); if (prio == nullptr) - throw AuthFailureException("Not enough memory for GnuTLS priority string"); + throw Exception("Not enough memory for GnuTLS priority string"); strcpy(prio, gnutls_default_priority); strcat(prio, kx_anon_priority); @@ -257,22 +263,25 @@ void CSecurityTLS::setParam() if (ret != GNUTLS_E_SUCCESS) { if (ret == GNUTLS_E_INVALID_REQUEST) vlog.error("GnuTLS priority syntax error at: %s", err); - throw AuthFailureException("gnutls_set_priority_direct failed"); + throw rdr::TLSException("gnutls_set_priority_direct()", ret); } #endif } if (anon) { - if (gnutls_anon_allocate_client_credentials(&anon_cred) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_anon_allocate_client_credentials failed"); + ret = gnutls_anon_allocate_client_credentials(&anon_cred); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_anon_allocate_client_credentials()", ret); - if (gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_credentials_set failed"); + ret = gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_credentials_set()", ret); vlog.debug("Anonymous session has been set"); } else { - if (gnutls_certificate_allocate_credentials(&cert_cred) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_certificate_allocate_credentials failed"); + ret = gnutls_certificate_allocate_credentials(&cert_cred); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_certificate_allocate_credentials()", ret); if (gnutls_certificate_set_x509_system_trust(cert_cred) < 1) vlog.error("Could not load system certificate trust store"); @@ -283,8 +292,9 @@ void CSecurityTLS::setParam() if (gnutls_certificate_set_x509_crl_file(cert_cred, X509CRL, GNUTLS_X509_FMT_PEM) < 0) vlog.error("Could not load user specified certificate revocation list"); - if (gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_credentials_set failed"); + ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_credentials_set()", ret); if (gnutls_server_name_set(session, GNUTLS_NAME_DNS, client->getServerName(), @@ -306,7 +316,7 @@ void CSecurityTLS::checkSession() unsigned int status; const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; - int err; + int err, known; bool hostname_match; const char *hostsDir; @@ -317,12 +327,12 @@ void CSecurityTLS::checkSession() return; if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509) - throw AuthFailureException("unsupported certificate type"); + throw Exception("unsupported certificate type"); err = gnutls_certificate_verify_peers2(session, &status); if (err != 0) { vlog.error("server certificate verification failed: %s", gnutls_strerror(err)); - throw AuthFailureException("server certificate verification failed"); + throw rdr::TLSException("server certificate verification()", err); } if (status != 0) { @@ -340,11 +350,11 @@ void CSecurityTLS::checkSession() 0) < 0) throw Exception("Failed to get certificate error description"); - error = format("Invalid server certificate: %s", status_str.data); + error = (const char*)status_str.data; gnutls_free(status_str.data); - throw AuthFailureException(error.c_str()); + throw Exception("Invalid server certificate: %s", error.c_str()); } if (gnutls_certificate_verification_status_print(status, @@ -362,14 +372,14 @@ void CSecurityTLS::checkSession() cert_list = gnutls_certificate_get_peers(session, &cert_list_size); if (!cert_list_size) - throw AuthFailureException("empty certificate chain"); + throw Exception("empty certificate chain"); /* Process only server's certificate, not issuer's certificate */ gnutls_x509_crt_t crt; gnutls_x509_crt_init(&crt); if (gnutls_x509_crt_import(crt, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) - throw AuthFailureException("decoding of certificate failed"); + throw Exception("decoding of certificate failed"); if (gnutls_x509_crt_check_hostname(crt, client->getServerName()) == 0) { vlog.info("Server certificate doesn't match given server name"); @@ -388,31 +398,32 @@ void CSecurityTLS::checkSession() hostsDir = os::getvncstatedir(); if (hostsDir == nullptr) { - throw AuthFailureException("Could not obtain VNC state directory " - "path for known hosts storage"); + throw Exception("Could not obtain VNC state directory path for " + "known hosts storage"); } std::string dbPath; dbPath = (std::string)hostsDir + "/x509_known_hosts"; - err = gnutls_verify_stored_pubkey(dbPath.c_str(), nullptr, - client->getServerName(), nullptr, - GNUTLS_CRT_X509, &cert_list[0], 0); + known = gnutls_verify_stored_pubkey(dbPath.c_str(), nullptr, + client->getServerName(), nullptr, + GNUTLS_CRT_X509, &cert_list[0], 0); /* Previously known? */ - if (err == GNUTLS_E_SUCCESS) { + if (known == GNUTLS_E_SUCCESS) { vlog.info("Server certificate found in known hosts file"); gnutls_x509_crt_deinit(crt); return; } - if ((err != GNUTLS_E_NO_CERTIFICATE_FOUND) && - (err != GNUTLS_E_CERTIFICATE_KEY_MISMATCH)) { - throw AuthFailureException("Could not load known hosts database"); + if ((known != GNUTLS_E_NO_CERTIFICATE_FOUND) && + (known != GNUTLS_E_CERTIFICATE_KEY_MISMATCH)) { + throw rdr::TLSException("Could not load known hosts database", known); } - if (gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_ONELINE, &info)) - throw AuthFailureException("Could not find certificate to display"); + err = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_ONELINE, &info); + if (err != GNUTLS_E_SUCCESS) + throw rdr::TLSException("Could not find certificate to display", err); len = strlen((char*)info.data); for (size_t i = 0; i < len - 1; i++) { @@ -421,7 +432,7 @@ void CSecurityTLS::checkSession() } /* New host */ - if (err == GNUTLS_E_NO_CERTIFICATE_FOUND) { + if (known == GNUTLS_E_NO_CERTIFICATE_FOUND) { std::string text; vlog.info("Server host not previously known"); @@ -510,7 +521,7 @@ void CSecurityTLS::checkSession() if (status != 0) { vlog.error("Unhandled certificate problems: 0x%x", status); - throw AuthFailureException("Unhandled certificate problems"); + throw Exception("Unhandled certificate problems"); } if (!hostname_match) { @@ -530,7 +541,7 @@ void CSecurityTLS::checkSession() text.c_str())) throw AuthCancelledException(); } - } else if (err == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) { + } else if (known == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) { std::string text; vlog.info("Server host key mismatch"); @@ -626,7 +637,7 @@ void CSecurityTLS::checkSession() if (status != 0) { vlog.error("Unhandled certificate problems: 0x%x", status); - throw AuthFailureException("Unhandled certificate problems"); + throw Exception("Unhandled certificate problems"); } if (!hostname_match) { diff --git a/common/rfb/CSecurityVeNCrypt.cxx b/common/rfb/CSecurityVeNCrypt.cxx index 19dcabc3..d6354976 100644 --- a/common/rfb/CSecurityVeNCrypt.cxx +++ b/common/rfb/CSecurityVeNCrypt.cxx @@ -107,7 +107,7 @@ bool CSecurityVeNCrypt::processMsg() os->writeU8(0); os->writeU8(0); os->flush(); - throw AuthFailureException("The server reported an unsupported VeNCrypt version"); + throw Exception("The server reported an unsupported VeNCrypt version"); } haveSentVersion = true; @@ -119,8 +119,8 @@ bool CSecurityVeNCrypt::processMsg() return false; if (is->readU8()) - throw AuthFailureException("The server reported it could not support the " - "VeNCrypt version"); + throw Exception("The server reported it could not support the " + "VeNCrypt version"); haveAgreedVersion = true; } @@ -133,7 +133,7 @@ bool CSecurityVeNCrypt::processMsg() nAvailableTypes = is->readU8(); if (!nAvailableTypes) - throw AuthFailureException("The server reported no VeNCrypt sub-types"); + throw Exception("The server reported no VeNCrypt sub-types"); availableTypes = new uint32_t[nAvailableTypes]; haveNumberOfTypes = true; @@ -174,7 +174,7 @@ bool CSecurityVeNCrypt::processMsg() /* Set up the stack according to the chosen type: */ if (chosenType == secTypeInvalid || chosenType == secTypeVeNCrypt) - throw AuthFailureException("No valid VeNCrypt sub-type"); + throw Exception("No valid VeNCrypt sub-type"); vlog.info("Choosing security type %s (%d)", secTypeName(chosenType), chosenType); @@ -193,7 +193,7 @@ bool CSecurityVeNCrypt::processMsg() * happen, since if the server supports 0 sub-types, it doesn't support * this security type */ - throw AuthFailureException("The server reported 0 VeNCrypt sub-types"); + throw Exception("The server reported 0 VeNCrypt sub-types"); } return csecurity->processMsg(); diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx index 69c6d9ca..e009de39 100644 --- a/common/rfb/SSecurityPlain.cxx +++ b/common/rfb/SSecurityPlain.cxx @@ -87,7 +87,7 @@ bool SSecurityPlain::processMsg() char password[1024]; if (!valid) - throw AuthFailureException("No password validator configured"); + throw Exception("No password validator configured"); if (state == 0) { if (!is->hasData(8)) diff --git a/common/rfb/SSecurityRSAAES.cxx b/common/rfb/SSecurityRSAAES.cxx index 4aa39111..530dca16 100644 --- a/common/rfb/SSecurityRSAAES.cxx +++ b/common/rfb/SSecurityRSAAES.cxx @@ -565,7 +565,7 @@ void SSecurityRSAAES::verifyUserPass() } delete valid; #else - throw AuthFailureException("No password validator configured"); + throw Exception("No password validator configured"); #endif } @@ -576,7 +576,7 @@ void SSecurityRSAAES::verifyPass() pg->getVncAuthPasswd(&passwd, &passwdReadOnly); if (passwd.empty()) - throw AuthFailureException("No password configured for VNC Auth"); + throw Exception("No password configured"); if (password == passwd) { accessRights = AccessDefault; diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx index e2b82f89..67dced6c 100644 --- a/common/rfb/SSecurityTLS.cxx +++ b/common/rfb/SSecurityTLS.cxx @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -71,12 +72,15 @@ SSecurityTLS::SSecurityTLS(SConnection* sc_, bool _anon) cert_cred(nullptr), anon(_anon), tlsis(nullptr), tlsos(nullptr), rawis(nullptr), rawos(nullptr) { + int ret; + #if defined (SSECURITYTLS__USE_DEPRECATED_DH) dh_params = nullptr; #endif - if (gnutls_global_init() != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_global_init failed"); + ret = gnutls_global_init(); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_global_init()", ret); } void SSecurityTLS::shutdown() @@ -138,17 +142,21 @@ SSecurityTLS::~SSecurityTLS() bool SSecurityTLS::processMsg() { + int err; + vlog.debug("Process security message (session %p)", session); if (!session) { rdr::InStream* is = sc->getInStream(); rdr::OutStream* os = sc->getOutStream(); - if (gnutls_init(&session, GNUTLS_SERVER) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_init failed"); + err = gnutls_init(&session, GNUTLS_SERVER); + if (err != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_init()", err); - if (gnutls_set_default_priority(session) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_set_default_priority failed"); + err = gnutls_set_default_priority(session); + if (err != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_set_default_priority()", err); try { setParams(); @@ -170,7 +178,6 @@ bool SSecurityTLS::processMsg() rawos = os; } - int err; err = gnutls_handshake(session); if (err != GNUTLS_E_SUCCESS) { if (!gnutls_error_is_fatal(err)) { @@ -179,7 +186,7 @@ bool SSecurityTLS::processMsg() } vlog.error("TLS Handshake failed: %s", gnutls_strerror (err)); shutdown(); - throw AuthFailureException("TLS Handshake failed"); + throw rdr::TLSException("TLS Handshake failed", err); } vlog.debug("TLS handshake completed with %s", @@ -204,7 +211,7 @@ void SSecurityTLS::setParams() prio = (char*)malloc(strlen(Security::GnuTLSPriority) + strlen(kx_anon_priority) + 1); if (prio == nullptr) - throw AuthFailureException("Not enough memory for GnuTLS priority string"); + throw Exception("Not enough memory for GnuTLS priority string"); strcpy(prio, Security::GnuTLSPriority); if (anon) @@ -217,7 +224,7 @@ void SSecurityTLS::setParams() if (ret != GNUTLS_E_SUCCESS) { if (ret == GNUTLS_E_INVALID_REQUEST) vlog.error("GnuTLS priority syntax error at: %s", err); - throw AuthFailureException("gnutls_set_priority_direct failed"); + throw rdr::TLSException("gnutls_set_priority_direct()", ret); } } else if (anon) { const char *err; @@ -229,7 +236,7 @@ void SSecurityTLS::setParams() if (ret != GNUTLS_E_SUCCESS) { if (ret == GNUTLS_E_INVALID_REQUEST) vlog.error("GnuTLS priority syntax error at: %s", err); - throw AuthFailureException("gnutls_set_default_priority_append failed"); + throw rdr::TLSException("gnutls_set_default_priority_append()", ret); } #else // We don't know what the system default priority is, so we guess @@ -240,7 +247,7 @@ void SSecurityTLS::setParams() prio = (char*)malloc(strlen(gnutls_default_priority) + strlen(kx_anon_priority) + 1); if (prio == nullptr) - throw AuthFailureException("Not enough memory for GnuTLS priority string"); + throw Exception("Not enough memory for GnuTLS priority string"); strcpy(prio, gnutls_default_priority); strcat(prio, kx_anon_priority); @@ -252,36 +259,41 @@ void SSecurityTLS::setParams() if (ret != GNUTLS_E_SUCCESS) { if (ret == GNUTLS_E_INVALID_REQUEST) vlog.error("GnuTLS priority syntax error at: %s", err); - throw AuthFailureException("gnutls_set_priority_direct failed"); + throw rdr::TLSException("gnutls_set_priority_direct()", ret); } #endif } #if defined (SSECURITYTLS__USE_DEPRECATED_DH) - if (gnutls_dh_params_init(&dh_params) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_dh_params_init failed"); - - if (gnutls_dh_params_import_pkcs3(dh_params, &ffdhe_pkcs3_param, GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_dh_params_import_pkcs3 failed"); + ret = gnutls_dh_params_init(&dh_params); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_dh_params_init()", ret); + + ret = gnutls_dh_params_import_pkcs3(dh_params, &ffdhe_pkcs3_param, + GNUTLS_X509_FMT_PEM); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_dh_params_import_pkcs3()", ret); #endif if (anon) { - if (gnutls_anon_allocate_server_credentials(&anon_cred) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_anon_allocate_server_credentials failed"); + ret = gnutls_anon_allocate_server_credentials(&anon_cred); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_anon_allocate_server_credentials()", ret); #if defined (SSECURITYTLS__USE_DEPRECATED_DH) gnutls_anon_set_server_dh_params(anon_cred, dh_params); #endif - if (gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred) - != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_credentials_set failed"); + ret = gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_credentials_set()", ret); vlog.debug("Anonymous session has been set"); } else { - if (gnutls_certificate_allocate_credentials(&cert_cred) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_certificate_allocate_credentials failed"); + ret = gnutls_certificate_allocate_credentials(&cert_cred); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_certificate_allocate_credentials()", ret); #if defined (SSECURITYTLS__USE_DEPRECATED_DH) gnutls_certificate_set_dh_params(cert_cred, dh_params); @@ -291,16 +303,16 @@ void SSecurityTLS::setParams() case GNUTLS_E_SUCCESS: break; case GNUTLS_E_CERTIFICATE_KEY_MISMATCH: - throw AuthFailureException("Private key does not match certificate"); + throw Exception("Private key does not match certificate"); case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE: - throw AuthFailureException("Unsupported certificate type"); + throw Exception("Unsupported certificate type"); default: - throw AuthFailureException("Error loading X509 certificate or key"); + throw Exception("Error loading X509 certificate or key"); } - if (gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred) - != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_credentials_set failed"); + ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred); + if (ret != GNUTLS_E_SUCCESS) + throw rdr::TLSException("gnutls_credentials_set()", ret); vlog.debug("X509 session has been set"); diff --git a/common/rfb/SSecurityVeNCrypt.cxx b/common/rfb/SSecurityVeNCrypt.cxx index ce160503..27ee1fe2 100644 --- a/common/rfb/SSecurityVeNCrypt.cxx +++ b/common/rfb/SSecurityVeNCrypt.cxx @@ -101,8 +101,8 @@ bool SSecurityVeNCrypt::processMsg() case 0x0001: /* 0.1 Legacy VeNCrypt, not supported */ os->writeU8(0xFF); /* This is not OK */ os->flush(); - throw AuthFailureException("The client cannot support the server's " - "VeNCrypt version"); + throw Exception("The client cannot support the server's " + "VeNCrypt version"); case 0x0002: /* 0.2 */ os->writeU8(0); /* OK */ @@ -111,7 +111,7 @@ bool SSecurityVeNCrypt::processMsg() default: os->writeU8(0xFF); /* Not OK */ os->flush(); - throw AuthFailureException("The client returned an unsupported VeNCrypt version"); + throw Exception("The client returned an unsupported VeNCrypt version"); } } @@ -140,7 +140,7 @@ bool SSecurityVeNCrypt::processMsg() os->flush(); haveSentTypes = true; } else - throw AuthFailureException("There are no VeNCrypt sub-types to send to the client"); + throw Exception("There are no VeNCrypt sub-types to send to the client"); } /* get type back from client (must be one of the ones we sent) */ @@ -165,7 +165,7 @@ bool SSecurityVeNCrypt::processMsg() /* Set up the stack according to the chosen type */ if (chosenType == secTypeInvalid || chosenType == secTypeVeNCrypt) - throw AuthFailureException("No valid VeNCrypt sub-type"); + throw Exception("No valid VeNCrypt sub-type"); ssecurity = security->GetSSecurity(sc, chosenType); } diff --git a/common/rfb/SSecurityVncAuth.cxx b/common/rfb/SSecurityVncAuth.cxx index 500903a8..272c7ca1 100644 --- a/common/rfb/SSecurityVncAuth.cxx +++ b/common/rfb/SSecurityVncAuth.cxx @@ -100,7 +100,7 @@ bool SSecurityVncAuth::processMsg() pg->getVncAuthPasswd(&passwd, &passwdReadOnly); if (passwd.empty()) - throw AuthFailureException("No password configured for VNC Auth"); + throw Exception("No password configured"); if (verifyResponse(passwd.c_str())) { accessRights = AccessDefault; -- 2.39.5