mirror of
https://github.com/KDE/krfb
synced 2026-07-01 15:31:19 -07:00
Design fixes: move the event handling back to the RfbClient and improve password handling.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195291
This commit is contained in:
@@ -39,6 +39,7 @@ public:
|
||||
: RfbClient(client, parent) {}
|
||||
|
||||
virtual rfbNewClientAction doHandle();
|
||||
virtual bool checkPassword(const QByteArray & encryptedPassword);
|
||||
};
|
||||
|
||||
rfbNewClientAction InvitationsRfbClient::doHandle()
|
||||
@@ -54,27 +55,47 @@ rfbNewClientAction InvitationsRfbClient::doHandle()
|
||||
return RfbClient::doHandle();
|
||||
}
|
||||
|
||||
//***********
|
||||
|
||||
static bool doCheckPassword(const QString &p, unsigned char *ochallenge, const char *response, int len)
|
||||
bool InvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword)
|
||||
{
|
||||
if ((len == 0) && (p.length() == 0)) {
|
||||
return true;
|
||||
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
|
||||
QByteArray password = KrfbConfig::uninvitedConnectionPassword().toLocal8Bit();
|
||||
|
||||
bool authd = false;
|
||||
kDebug() << "about to start autentication";
|
||||
|
||||
if (allowUninvited) {
|
||||
authd = vncAuthCheckPassword(password, encryptedPassword);
|
||||
}
|
||||
|
||||
char passwd[MAXPWLEN];
|
||||
unsigned char challenge[CHALLENGESIZE];
|
||||
if (!authd) {
|
||||
QList<Invitation> invlist = InvitationManager::self()->invitations();
|
||||
|
||||
memcpy(challenge, ochallenge, CHALLENGESIZE);
|
||||
bzero(passwd, MAXPWLEN);
|
||||
foreach(const Invitation & it, invlist) {
|
||||
kDebug() << "checking password";
|
||||
|
||||
if (!p.isNull()) {
|
||||
strncpy(passwd, p.toLatin1(),
|
||||
(MAXPWLEN <= p.length()) ? MAXPWLEN : p.length());
|
||||
if (vncAuthCheckPassword(it.password().toLocal8Bit(), encryptedPassword)
|
||||
&& it.isValid())
|
||||
{
|
||||
authd = true;
|
||||
InvitationManager::self()->removeInvitation(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rfbEncryptBytes(challenge, passwd);
|
||||
return memcmp(challenge, response, len) == 0;
|
||||
if (!authd) {
|
||||
if (InvitationManager::self()->invitations().size() > 0) {
|
||||
KNotification::event("InvalidPasswordInvitations",
|
||||
i18n("Failed login attempt from %1: wrong password", name()));
|
||||
} else {
|
||||
KNotification::event("InvalidPassword",
|
||||
i18n("Failed login attempt from %1: wrong password", name()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//***********
|
||||
@@ -95,52 +116,6 @@ RfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
|
||||
return new InvitationsRfbClient(client, this);
|
||||
}
|
||||
|
||||
bool InvitationsRfbServer::checkPassword(RfbClient* client, const char* encryptedPassword, int len)
|
||||
{
|
||||
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
|
||||
QString password = KrfbConfig::uninvitedConnectionPassword();
|
||||
|
||||
bool authd = false;
|
||||
kDebug() << "about to start autentication";
|
||||
|
||||
if (allowUninvited) {
|
||||
authd = doCheckPassword(password, client->rfbClient()->authChallenge, encryptedPassword, len);
|
||||
}
|
||||
|
||||
if (!authd) {
|
||||
QList<Invitation> invlist = InvitationManager::self()->invitations();
|
||||
|
||||
foreach(const Invitation & it, invlist) {
|
||||
kDebug() << "checking password";
|
||||
|
||||
if (doCheckPassword(it.password(), client->rfbClient()->authChallenge,
|
||||
encryptedPassword, len)
|
||||
&& it.isValid())
|
||||
{
|
||||
authd = true;
|
||||
InvitationManager::self()->removeInvitation(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!authd) {
|
||||
if (InvitationManager::self()->invitations().size() > 0) {
|
||||
KNotification::event("InvalidPasswordInvitations",
|
||||
i18n("Failed login attempt from %1: wrong password",
|
||||
client->name()));
|
||||
} else {
|
||||
KNotification::event("InvalidPassword",
|
||||
i18n("Failed login attempt from %1: wrong password",
|
||||
client->name()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InvitationsRfbServer::startAndCheck()
|
||||
{
|
||||
if (!start()) {
|
||||
|
||||
@@ -32,7 +32,6 @@ protected:
|
||||
InvitationsRfbServer() : RfbServer(0) {}
|
||||
|
||||
virtual RfbClient* newClient(rfbClientPtr client);
|
||||
virtual bool checkPassword(RfbClient* client, const char* encryptedPassword, int len);
|
||||
|
||||
private Q_SLOTS:
|
||||
void startAndCheck();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "connectiondialog.h"
|
||||
#include "krfbconfig.h"
|
||||
#include "sockethelpers.h"
|
||||
#include "events.h"
|
||||
#include <QtCore/QSocketNotifier>
|
||||
#include <KDebug>
|
||||
#include <KNotification>
|
||||
@@ -78,11 +79,6 @@ void RfbClient::setControlEnabled(bool enabled)
|
||||
}
|
||||
}
|
||||
|
||||
rfbClientPtr RfbClient::rfbClient() const
|
||||
{
|
||||
return d->client;
|
||||
}
|
||||
|
||||
void RfbClient::update()
|
||||
{
|
||||
rfbUpdateClient(d->client);
|
||||
@@ -154,6 +150,48 @@ void RfbClient::setStatusConnected()
|
||||
}
|
||||
}
|
||||
|
||||
void RfbClient::handleKeyboardEvent(bool down, rfbKeySym keySym)
|
||||
{
|
||||
if (d->controlEnabled) {
|
||||
EventHandler::handleKeyboard(down, keySym);
|
||||
}
|
||||
}
|
||||
|
||||
void RfbClient::handleMouseEvent(int buttonMask, int x, int y)
|
||||
{
|
||||
if (d->controlEnabled) {
|
||||
EventHandler::handlePointer(buttonMask, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
bool RfbClient::checkPassword(const QByteArray & encryptedPassword)
|
||||
{
|
||||
Q_UNUSED(encryptedPassword);
|
||||
|
||||
return d->client->screen->authPasswdData == (void*)0;
|
||||
}
|
||||
|
||||
bool RfbClient::vncAuthCheckPassword(const QByteArray& password, const QByteArray& encryptedPassword) const
|
||||
{
|
||||
if (password.isEmpty() && encryptedPassword.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char passwd[MAXPWLEN];
|
||||
unsigned char challenge[CHALLENGESIZE];
|
||||
|
||||
memcpy(challenge, d->client->authChallenge, CHALLENGESIZE);
|
||||
bzero(passwd, MAXPWLEN);
|
||||
|
||||
if (!password.isEmpty()) {
|
||||
strncpy(passwd, password,
|
||||
(MAXPWLEN <= password.size()) ? MAXPWLEN : password.size());
|
||||
}
|
||||
|
||||
rfbEncryptBytes(challenge, passwd);
|
||||
return memcmp(challenge, encryptedPassword, encryptedPassword.size()) == 0;
|
||||
}
|
||||
|
||||
void RfbClient::onSocketActivated()
|
||||
{
|
||||
//Process not only one, but all pending messages.
|
||||
|
||||
@@ -38,9 +38,6 @@ public:
|
||||
bool controlEnabled() const;
|
||||
void setControlEnabled(bool enabled);
|
||||
|
||||
///returns the internal rfbClient
|
||||
rfbClientPtr rfbClient() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setOnHold(bool onHold);
|
||||
void closeConnection();
|
||||
@@ -63,6 +60,23 @@ protected:
|
||||
bool isConnected() const;
|
||||
void setStatusConnected(); ///call to declare the client as connected
|
||||
|
||||
virtual void handleKeyboardEvent(bool down, rfbKeySym keySym);
|
||||
virtual void handleMouseEvent(int buttonMask, int x, int y);
|
||||
|
||||
/** This method is supposed to check if the provided \a encryptedPassword
|
||||
* matches the criteria for authenticating the client.
|
||||
* The default implementation returns false if a password is required.
|
||||
* Reimplement to do more useful stuff.
|
||||
*/
|
||||
virtual bool checkPassword(const QByteArray & encryptedPassword);
|
||||
|
||||
/** This method checks if the \a encryptedPassword that was sent from the remote
|
||||
* user matches the \a password that you have specified localy to be the password
|
||||
* for this connection. This assumes that the standard VNC authentication mechanism
|
||||
* is used. Returns true if the password matches or false otherwise.
|
||||
*/
|
||||
bool vncAuthCheckPassword(const QByteArray & password, const QByteArray & encryptedPassword) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onSocketActivated();
|
||||
void dialogAccepted();
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "rfbserver.h"
|
||||
#include "events.h"
|
||||
#include "rfbservermanager.h"
|
||||
#include <QtCore/QSocketNotifier>
|
||||
#include <KDebug>
|
||||
@@ -55,32 +54,6 @@ RfbServer::~RfbServer()
|
||||
RfbServerManager::instance()->unregisterServer(this);
|
||||
}
|
||||
|
||||
void RfbServer::handleKeyboardEvent(RfbClient* client, rfbBool down, rfbKeySym keySym)
|
||||
{
|
||||
if (client->controlEnabled()) {
|
||||
EventHandler::handleKeyboard(down, keySym);
|
||||
}
|
||||
}
|
||||
|
||||
void RfbServer::handleMouseEvent(RfbClient* client, int buttonMask, int x, int y)
|
||||
{
|
||||
if (client->controlEnabled()) {
|
||||
EventHandler::handlePointer(buttonMask, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/** Default implementation returns false if a password is required.
|
||||
* Reimplement to do more useful stuff
|
||||
*/
|
||||
bool RfbServer::checkPassword(RfbClient* client, const char* encryptedPassword, int len)
|
||||
{
|
||||
Q_UNUSED(client);
|
||||
Q_UNUSED(encryptedPassword);
|
||||
Q_UNUSED(len);
|
||||
|
||||
return !d->passwordRequired;
|
||||
}
|
||||
|
||||
QByteArray RfbServer::listeningAddress() const
|
||||
{
|
||||
return d->listeningAddress;
|
||||
@@ -259,25 +232,22 @@ void RfbServer::clientGoneHook(rfbClientPtr cl)
|
||||
//static
|
||||
rfbBool RfbServer::passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len)
|
||||
{
|
||||
RfbServer *server = static_cast<RfbServer*>(cl->screen->screenData);
|
||||
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
|
||||
return server->checkPassword(client, encryptedPassword, len);
|
||||
return client->checkPassword(QByteArray::fromRawData(encryptedPassword, len));
|
||||
}
|
||||
|
||||
//static
|
||||
void RfbServer::keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
|
||||
{
|
||||
RfbServer *server = static_cast<RfbServer*>(cl->screen->screenData);
|
||||
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
|
||||
server->handleKeyboardEvent(client, down ? true : false, keySym);
|
||||
client->handleKeyboardEvent(down ? true : false, keySym);
|
||||
}
|
||||
|
||||
//static
|
||||
void RfbServer::pointerHook(int bm, int x, int y, rfbClientPtr cl)
|
||||
{
|
||||
RfbServer *server = static_cast<RfbServer*>(cl->screen->screenData);
|
||||
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
|
||||
server->handleMouseEvent(client, bm, x, y);
|
||||
client->handleMouseEvent(bm, x, y);
|
||||
}
|
||||
|
||||
//static
|
||||
|
||||
@@ -52,10 +52,6 @@ private Q_SLOTS:
|
||||
protected:
|
||||
virtual RfbClient *newClient(rfbClientPtr client) = 0;
|
||||
|
||||
virtual void handleKeyboardEvent(RfbClient *client, rfbBool down, rfbKeySym keySym);
|
||||
virtual void handleMouseEvent(RfbClient *client, int buttonMask, int x, int y);
|
||||
virtual bool checkPassword(RfbClient *client, const char *encryptedPassword, int len);
|
||||
|
||||
private:
|
||||
static rfbNewClientAction newClientHook(rfbClientPtr cl);
|
||||
static void clientGoneHook(rfbClientPtr cl);
|
||||
|
||||
Reference in New Issue
Block a user