1 /* This file is part of the KDE project
2 Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
3 (C) 2001-2003 by Tim Jansen <tim@tjansen.de>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 #include "connectioncontroller.h"
11 #include "connectioncontroller.moc"
15 #include <QApplication>
16 #include <QDesktopWidget>
23 #include <KNotification>
28 #include "invitationmanager.h"
29 #include "connectiondialog.h"
31 #include "krfbserver.h"
33 #include "krfbconfig.h"
35 #include <X11/Xutil.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
41 static QString
peerAddress(int sock
) {
43 const int ADDR_SIZE
= 50;
45 socklen_t salen
= sizeof(struct sockaddr
);
46 if (getpeername(sock
, &sa
, &salen
) == 0) {
47 if (sa
.sa_family
== AF_INET
) {
48 struct sockaddr_in
*si
= (struct sockaddr_in
*)&sa
;
49 return QString(inet_ntoa(si
->sin_addr
));
51 if (sa
.sa_family
== AF_INET6
) {
52 char inetbuf
[ADDR_SIZE
];
53 inet_ntop(sa
.sa_family
, &sa
, inetbuf
, ADDR_SIZE
);
54 return QString(inetbuf
);
56 return QString("not a network address");
58 return QString("unable to determine...");
61 static void clientGoneHook(rfbClientPtr cl
)
63 ConnectionController
*cc
= static_cast<ConnectionController
*>(cl
->clientData
);
64 cc
->handleClientGone();
68 static bool checkPassword(const QString
&p
, unsigned char *ochallenge
, const char *response
, int len
)
71 if ((len
== 0) && (p
.length() == 0)) {
75 char passwd
[MAXPWLEN
];
76 unsigned char challenge
[CHALLENGESIZE
];
78 memcpy(challenge
, ochallenge
, CHALLENGESIZE
);
79 bzero(passwd
, MAXPWLEN
);
81 strncpy(passwd
, p
.toLatin1(),
82 (MAXPWLEN
<= p
.length()) ? MAXPWLEN
: p
.length());
85 rfbEncryptBytes(challenge
, passwd
);
86 return memcmp(challenge
, response
, len
) == 0;
90 ConnectionController::ConnectionController(struct _rfbClientRec
*_cl
, KrfbServer
* parent
)
91 : QObject(parent
), cl(_cl
)
93 cl
->clientData
= (void*)this;
96 ConnectionController::~ConnectionController()
100 enum rfbNewClientAction
ConnectionController::handleNewClient()
103 bool askOnConnect
= KrfbConfig::askOnConnect();
104 bool allowUninvited
= KrfbConfig::allowUninvitedConnections();
106 remoteIp
= peerAddress(cl
->sock
);
108 if (!allowUninvited
&& InvitationManager::self()->activeInvitations() == 0) {
109 KNotification::event("ConnectionAttempted",
110 i18n("Refused uninvited connection attempt from %1",
112 return RFB_CLIENT_REFUSE
;
115 if (!askOnConnect
&& InvitationManager::self()->activeInvitations() == 0) {
116 KNotification::event("NewConnectionAutoAccepted",
117 i18n("Accepted uninvited connection from %1",
120 emit
sessionEstablished(remoteIp
);
121 return RFB_CLIENT_ACCEPT
;
124 KNotification::event("NewConnectionOnHold",
125 i18n("Received connection from %1, on hold (waiting for confirmation)",
128 cl
->clientGoneHook
= clientGoneHook
;
130 ConnectionDialog
*dialog
= new ConnectionDialog(0);
131 dialog
->setRemoteHost(remoteIp
);
132 dialog
->setAllowRemoteControl( true );
134 connect(dialog
, SIGNAL(okClicked()), SLOT(dialogAccepted()));
135 connect(dialog
, SIGNAL(cancelClicked()), SLOT(dialogRejected()));
139 return RFB_CLIENT_ON_HOLD
;
142 bool ConnectionController::handleCheckPassword(rfbClientPtr cl
, const char *response
, int len
)
144 bool allowUninvited
= KrfbConfig::allowUninvitedConnections();
145 QString password
= KrfbConfig::uninvitedConnectionPassword();
148 kDebug() << "about to start autentication";
150 if (allowUninvited
) {
151 authd
= checkPassword(password
, cl
->authChallenge
, response
, len
);
155 QList
<Invitation
> invlist
= InvitationManager::self()->invitations();
157 foreach(const Invitation
&it
, invlist
) {
158 kDebug() << "checking password";
159 if (checkPassword(it
.password(), cl
->authChallenge
, response
, len
) && it
.isValid()) {
161 InvitationManager::self()->removeInvitation(it
);
168 if (InvitationManager::self()->invitations().size() > 0) {
169 KNotification::event("InvalidPasswordInvitations",
170 i18n("Failed login attempt from %1: wrong password",
173 KNotification::event("InvalidPassword",
174 i18n("Failed login attempt from %1: wrong password",
185 void ConnectionController::handleKeyEvent(bool down
, rfbKeySym keySym
)
187 if (controlEnabled
) {
188 KeyboardEvent
ev(down
, keySym
);
193 void ConnectionController::handlePointerEvent(int bm
, int x
, int y
)
195 if (controlEnabled
) {
196 PointerEvent
ev(bm
, x
, y
);
201 void ConnectionController::handleClientGone()
203 emit
clientDisconnected(this);
204 kDebug() << "client gone";
208 void ConnectionController::clipboardToServer(const QString
&s
)
210 ClipboardEvent
ev(this, s
);
214 void ConnectionController::dialogAccepted()
216 // rfbStartOnHoldClient(cl);
220 void ConnectionController::dialogRejected()
222 kDebug() << "refused connection";
223 rfbRefuseOnHoldClient(cl
);
226 void ConnectionController::setControlEnabled(bool enable
)
228 controlEnabled
= enable
;